private void Resolve(NetHttpContext context, IList list, WADLParam[] parameters) { Array.ForEach(parameters, delegate(WADLParam parameter) { list.Add(Resolve(context, parameter)); }); }
private Stream ProcessRequest() { if (State.CurrentStatus == ServiceStatus.FAULT) { WebOperationContext.Current.OutgoingResponse.Headers.Add("Server-Status", State.CurrentStatus.ToString()); WebOperationContext.Current.OutgoingResponse.Headers.Add("Server-Status-Message", System.Web.HttpUtility.UrlEncode(State.Message)); return(null); } else { WebOperationContext.Current.OutgoingResponse.Headers.Add("Server-Status", State.CurrentStatus.ToString()); } Stream output; using (NetHttpContext context = new NetHttpContext(WebOperationContext.Current, out output)) { NetHttpChannelDispatcher dispatcher = null; try { var matches = (from keys in Templates select keys).Where <NetHttpChannelDispatcher>(delegate(NetHttpChannelDispatcher item) { //return item.IsMatch(new Uri(Configuration.BaseUri), context.Request.Url); return(item.IsMatch(this.BaseUrl, context.Request.Url)); }).ToArray <NetHttpChannelDispatcher>(); switch (matches.Length) { case 0: throw new HttpException((int)HttpStatusCode.NotFound, "not found"); case 1: dispatcher = matches[0]; break; default: try { if (context.Request.Params.Count == 0) { var nonQuery = (from match in matches select match).Where(delegate(NetHttpChannelDispatcher item) { return(item.MatchType == MatchType.Static); }); if (nonQuery.Count() == 0) { nonQuery = (from match in matches select match).Where(delegate(NetHttpChannelDispatcher item) { return(item.MatchType == MatchType.Template); }); } dispatcher = nonQuery.Single(); } else { var query = (from match in matches select match).Where(delegate(NetHttpChannelDispatcher item) { return((item.MatchType & MatchType.Static) == MatchType.Static && (item.MatchType & MatchType.Query) == MatchType.Query); }); if (query.Count() == 0) { query = (from match in matches select match).Where(delegate(NetHttpChannelDispatcher item) { return((item.MatchType & MatchType.Query) == MatchType.Query); //&& item.Method.Parameters.Count() == context.Request.Params.Count; }); } if (query.Count() > 1) { query = (from match in query select match).Where(delegate(NetHttpChannelDispatcher item) { return((item.MatchType & MatchType.Query) == MatchType.Query && item.Method.Parameters.Count() == context.Request.Params.Count); }); } dispatcher = query.Single(); } } catch (InvalidOperationException) { int max = matches.Max <NetHttpChannelDispatcher>(m => ((NetHttpUriTemplate)m.Template).Url.GetMatchingSegments(context.Request.Url).Length); dispatcher = (from match in matches select match).Where(delegate(NetHttpChannelDispatcher candidate) { bool use = ((NetHttpUriTemplate)candidate.Template).Url.GetMatchingSegments(context.Request.Url).Length == max; if (context.Request.Params.Count == 0) { use = use && (((candidate.MatchType & MatchType.Static) == MatchType.Static) || ((candidate.MatchType & MatchType.Template) == MatchType.Template)); } else { use = use && ((candidate.MatchType & MatchType.Query) == MatchType.Query); } return(use); }).Single(); } break; } dispatcher.Invoke(context); } //TODO: Find best approach catch (HttpException httpException) { //context.Response.ContentType = "text/plain; charset=UTF-8"; //context.Response.StatusCode = (HttpStatusCode)httpException.GetHttpCode(); //context.Response.StatusDescription = httpException.Message; //context.Response.SetStatusAsNotFound(httpException.Message); switch (httpException.ErrorCode) { case 404: context.Response.SetStatusAsNotFound(httpException.Message); context.Response.SuppressEntityBody = true; break; default: throw httpException; } } catch (System.Exception exception) { var httpException = exception.InnerException as HttpException; if (httpException == null) { context.Response.ContentType = "text/plain; charset=UTF-8"; context.Response.StatusCode = HttpStatusCode.BadRequest; context.Response.StatusDescription = exception.Message; } else { switch (httpException.ErrorCode) { case 404: context.Response.SetStatusAsNotFound(httpException.Message); context.Response.SuppressEntityBody = true; break; default: throw exception.InnerException; } } } return(output); } }
private Stream ProcessRequest() { if (State.CurrentStatus == ServiceStatus.FAULT) { WebOperationContext.Current.OutgoingResponse.Headers.Add("Server-Status", State.CurrentStatus.ToString()); WebOperationContext.Current.OutgoingResponse.Headers.Add("Server-Status-Message", System.Web.HttpUtility.UrlEncode(State.Message)); return null; } else { WebOperationContext.Current.OutgoingResponse.Headers.Add("Server-Status", State.CurrentStatus.ToString()); } Stream output; using (NetHttpContext context = new NetHttpContext(WebOperationContext.Current, out output)) { NetHttpChannelDispatcher dispatcher = null; try { var matches = (from keys in Templates select keys).Where<NetHttpChannelDispatcher>(delegate(NetHttpChannelDispatcher item) { //return item.IsMatch(new Uri(Configuration.BaseUri), context.Request.Url); return item.IsMatch(this.BaseUrl, context.Request.Url); }).ToArray<NetHttpChannelDispatcher>(); switch (matches.Length) { case 0: throw new HttpException((int)HttpStatusCode.NotFound, "not found"); case 1: dispatcher = matches[0]; break; default: try { if (context.Request.Params.Count == 0) { var nonQuery = (from match in matches select match).Where(delegate(NetHttpChannelDispatcher item) { return item.MatchType == MatchType.Static; }); if (nonQuery.Count() == 0) { nonQuery = (from match in matches select match).Where(delegate(NetHttpChannelDispatcher item) { return item.MatchType == MatchType.Template; }); } dispatcher = nonQuery.Single(); } else { var query = (from match in matches select match).Where(delegate(NetHttpChannelDispatcher item) { return (item.MatchType & MatchType.Static) == MatchType.Static && (item.MatchType & MatchType.Query) == MatchType.Query; }); if (query.Count() == 0) { query = (from match in matches select match).Where(delegate(NetHttpChannelDispatcher item) { return (item.MatchType & MatchType.Query) == MatchType.Query; //&& item.Method.Parameters.Count() == context.Request.Params.Count; }); } if (query.Count() > 1) { query = (from match in query select match).Where(delegate(NetHttpChannelDispatcher item) { return (item.MatchType & MatchType.Query) == MatchType.Query && item.Method.Parameters.Count() == context.Request.Params.Count; }); } dispatcher = query.Single(); } } catch (InvalidOperationException) { int max = matches.Max<NetHttpChannelDispatcher>(m => ((NetHttpUriTemplate)m.Template).Url.GetMatchingSegments(context.Request.Url).Length); dispatcher = (from match in matches select match).Where(delegate(NetHttpChannelDispatcher candidate) { bool use = ((NetHttpUriTemplate)candidate.Template).Url.GetMatchingSegments(context.Request.Url).Length == max; if (context.Request.Params.Count == 0) { use = use && (((candidate.MatchType & MatchType.Static) == MatchType.Static) || ((candidate.MatchType & MatchType.Template) == MatchType.Template)); } else { use = use && ((candidate.MatchType & MatchType.Query) == MatchType.Query); } return use; }).Single(); } break; } dispatcher.Invoke(context); } //TODO: Find best approach catch (HttpException httpException) { //context.Response.ContentType = "text/plain; charset=UTF-8"; //context.Response.StatusCode = (HttpStatusCode)httpException.GetHttpCode(); //context.Response.StatusDescription = httpException.Message; //context.Response.SetStatusAsNotFound(httpException.Message); switch (httpException.ErrorCode) { case 404: context.Response.SetStatusAsNotFound(httpException.Message); context.Response.SuppressEntityBody = true; break; default: throw httpException; } } catch (System.Exception exception) { var httpException = exception.InnerException as HttpException; if (httpException == null) { context.Response.ContentType = "text/plain; charset=UTF-8"; context.Response.StatusCode = HttpStatusCode.BadRequest; context.Response.StatusDescription = exception.Message; } else { switch (httpException.ErrorCode) { case 404: context.Response.SetStatusAsNotFound(httpException.Message); context.Response.SuppressEntityBody = true; break; default: throw exception.InnerException; } } } return output; } }
//Type type = param.ParameterInfo.ParameterType; //if (String.IsNullOrEmpty(param.Encoding) || param.Encoding == ContentTypes.txt) //{ // if (type.IsArray) // { // type = Type.GetType(type.AssemblyQualifiedName.Replace("[]", "")); // } // return Convert(type, value); //} //else //{ // object obj = null; // TemplateConfigurationHandler handler = TemplateConfigurationHandler.GetConfiguration(); // Type encoder = Type.GetType(handler.Encoders[param.Encoding].Type); // IFormatter formatter = Activator.CreateInstance(encoder, new object[]{type}) as IFormatter; // using(Stream stream = new System.IO.MemoryStream()) // { // using (StreamWriter writer = new StreamWriter(stream)) // { // value = System.Web.HttpUtility.UrlDecode(value); // writer.Write(value); // obj = formatter.Deserialize(stream); // writer.Close(); // } // stream.Close(); // } // return obj; //} //static object Convert(Type type, string value) //{ // value = System.Web.HttpUtility.UrlDecode(value); // switch (System.Type.GetTypeCode(type)) // { // case TypeCode.Char: // return System.Convert.ToChar(value); // case TypeCode.SByte: // return System.Convert.ToSByte(value); // case TypeCode.UInt16: // return System.Convert.ToUInt16(value); // case TypeCode.UInt32: // return System.Convert.ToUInt32(value); // case TypeCode.UInt64: // return System.Convert.ToUInt64(value); ; // case TypeCode.Boolean: // return System.Convert.ToBoolean(value); // case TypeCode.Byte: // return System.Convert.ToByte(value); //? // case TypeCode.Int16: // return System.Convert.ToInt16(value); // case TypeCode.Int32: // return System.Convert.ToInt32(value); // case TypeCode.Int64: // return System.Convert.ToInt64(value); // case TypeCode.Single: // return System.Convert.ToSingle(value); // case TypeCode.Double: // return System.Convert.ToDouble(value); // case TypeCode.Decimal: // return System.Convert.ToDecimal(value); // case TypeCode.DateTime: // return System.Convert.ToDateTime(value); // case TypeCode.String: // return System.Convert.ToString(value); //can be any type in the event of a mismatch the app must catch it // case TypeCode.Object://check this // case TypeCode.Empty: // case TypeCode.DBNull: // default: // throw new NotSupportedException(String.Format("datatype {0}", type.Name)); // } //} private object Resolve(NetHttpContext context, WADLParam parameter) { string value = null; if (String.IsNullOrEmpty(parameter.Fixed)) { switch (parameter.Style) { case ParamStyles.Query: value = match.QueryParameters[parameter.Name]; if (String.IsNullOrEmpty(value)) { if (String.IsNullOrEmpty(parameter.Default)) { if (parameter.IsRequired) { throw new ArgumentNullException(parameter.Name); } else { return(null); } } else { value = parameter.Default; return(Decode(parameter, value)); } } else { return(Decode(parameter, value)); } case ParamStyles.Form: value = context.Request.Params[parameter.Name] ?? context.Request.Params["formBody"]; if (String.IsNullOrEmpty(value)) { if (String.IsNullOrEmpty(parameter.Default)) { if (parameter.IsRequired) { throw new ArgumentNullException(parameter.Name); } else { return(null); } } else { value = parameter.Default; return(Decode(parameter, value)); } } else { return(Decode(parameter, value)); } case ParamStyles.Template: value = match.BoundVariables[parameter.Name]; if (String.IsNullOrEmpty(value)) { if (String.IsNullOrEmpty(parameter.Default)) { if (parameter.IsRequired) { throw new ArgumentNullException(parameter.Name); } else { return(null); } } else { value = parameter.Default; return(Decode(parameter, value)); } } else { return(Decode(parameter, value)); } case ParamStyles.Header: value = context.Request.Headers[parameter.Name]; if (String.IsNullOrEmpty(value)) { if (String.IsNullOrEmpty(parameter.Default)) { if (parameter.IsRequired) { throw new ArgumentNullException(parameter.Name); } else { return(null); } } else { value = parameter.Default; return(Decode(parameter, value)); } } else { return(Decode(parameter, value)); } default: throw new ArgumentException(parameter.Style.ToString()); } } else { value = parameter.Fixed; return(Decode(parameter, value)); } }
//TODO: Method needs to be evaluated //deserialize parameters public void Invoke(NetHttpContext context) { List <object> parameters = new List <object>(); ParameterInfo[] @params = Method.MethodInfo.GetParameters(); Array.ForEach(@params, delegate(ParameterInfo param) { WADLParam[] attributes = WADLParam.GetWADLParams(param); if (param.ParameterType.IsArray) { Type type = Type.GetType(param.ParameterType.AssemblyQualifiedName.Replace("[]", "")); Array array = Array.CreateInstance(type, attributes.Length); IList list = Activator.CreateInstance(typeof(List <>).MakeGenericType(type)) as IList; Resolve(context, list, attributes); list.CopyTo(array, 0); parameters.Add(array); } else { if (attributes.Length == 0) { WADLParam wadlParam = WADLParam.CreateWADLParam(param); parameters.Add(Resolve(context, wadlParam)); } else { parameters.Add(Resolve(context, attributes.Single())); } } }); NetHttpChannelManager instanceToInvoke = Instance; if (Instance.GetInstancingModeAttribute() == InstancingMode.PerCall) { instanceToInvoke = Activator.CreateInstance(Instance.GetType()) as NetHttpChannelManager; } var result = Method.MethodInfo.Invoke(instanceToInvoke, parameters.ToArray()); if (result == null) { WebOperationContext.Current.OutgoingResponse.SetStatusAsNotFound(); WebOperationContext.Current.OutgoingResponse.SuppressEntityBody = true; } else { var outputs = (from representation in Method.Representations select representation).Where <WADLRepresentation>(delegate(WADLRepresentation rep) { return(rep.Status == System.Net.HttpStatusCode.OK); }); WADLRepresentation output; if (outputs.Count() == 1) { output = outputs.Single(); context.Response.ContentType = output.ContentType; } else { output = outputs.DefaultIfEmpty(null).SingleOrDefault(o => o.ContentType == context.Response.ContentType); if (output == null) { output = new WADLRepresentation(ContentTypes.unknown); context.Response.ContentType = output.ContentType; } } Encode(context.Response.Buffer, output, result); } }
//Type type = param.ParameterInfo.ParameterType; //if (String.IsNullOrEmpty(param.Encoding) || param.Encoding == ContentTypes.txt) //{ // if (type.IsArray) // { // type = Type.GetType(type.AssemblyQualifiedName.Replace("[]", "")); // } // return Convert(type, value); //} //else //{ // object obj = null; // TemplateConfigurationHandler handler = TemplateConfigurationHandler.GetConfiguration(); // Type encoder = Type.GetType(handler.Encoders[param.Encoding].Type); // IFormatter formatter = Activator.CreateInstance(encoder, new object[]{type}) as IFormatter; // using(Stream stream = new System.IO.MemoryStream()) // { // using (StreamWriter writer = new StreamWriter(stream)) // { // value = System.Web.HttpUtility.UrlDecode(value); // writer.Write(value); // obj = formatter.Deserialize(stream); // writer.Close(); // } // stream.Close(); // } // return obj; //} //static object Convert(Type type, string value) //{ // value = System.Web.HttpUtility.UrlDecode(value); // switch (System.Type.GetTypeCode(type)) // { // case TypeCode.Char: // return System.Convert.ToChar(value); // case TypeCode.SByte: // return System.Convert.ToSByte(value); // case TypeCode.UInt16: // return System.Convert.ToUInt16(value); // case TypeCode.UInt32: // return System.Convert.ToUInt32(value); // case TypeCode.UInt64: // return System.Convert.ToUInt64(value); ; // case TypeCode.Boolean: // return System.Convert.ToBoolean(value); // case TypeCode.Byte: // return System.Convert.ToByte(value); //? // case TypeCode.Int16: // return System.Convert.ToInt16(value); // case TypeCode.Int32: // return System.Convert.ToInt32(value); // case TypeCode.Int64: // return System.Convert.ToInt64(value); // case TypeCode.Single: // return System.Convert.ToSingle(value); // case TypeCode.Double: // return System.Convert.ToDouble(value); // case TypeCode.Decimal: // return System.Convert.ToDecimal(value); // case TypeCode.DateTime: // return System.Convert.ToDateTime(value); // case TypeCode.String: // return System.Convert.ToString(value); //can be any type in the event of a mismatch the app must catch it // case TypeCode.Object://check this // case TypeCode.Empty: // case TypeCode.DBNull: // default: // throw new NotSupportedException(String.Format("datatype {0}", type.Name)); // } //} private object Resolve(NetHttpContext context, WADLParam parameter) { string value = null; if (String.IsNullOrEmpty(parameter.Fixed)) { switch (parameter.Style) { case ParamStyles.Query: value = match.QueryParameters[parameter.Name]; if (String.IsNullOrEmpty(value)) { if (String.IsNullOrEmpty(parameter.Default)) { if (parameter.IsRequired) throw new ArgumentNullException(parameter.Name); else return null; } else { value = parameter.Default; return Decode(parameter, value); } } else return Decode(parameter, value); case ParamStyles.Form: value = context.Request.Params[parameter.Name] ?? context.Request.Params["formBody"]; if (String.IsNullOrEmpty(value)) { if (String.IsNullOrEmpty(parameter.Default)) { if (parameter.IsRequired) throw new ArgumentNullException(parameter.Name); else return null; } else { value = parameter.Default; return Decode(parameter, value); } } else return Decode(parameter, value); case ParamStyles.Template: value = match.BoundVariables[parameter.Name]; if (String.IsNullOrEmpty(value)) { if (String.IsNullOrEmpty(parameter.Default)) { if (parameter.IsRequired) throw new ArgumentNullException(parameter.Name); else return null; } else { value = parameter.Default; return Decode(parameter, value); } } else return Decode(parameter, value); case ParamStyles.Header: value = context.Request.Headers[parameter.Name]; if (String.IsNullOrEmpty(value)) { if (String.IsNullOrEmpty(parameter.Default)) { if (parameter.IsRequired) throw new ArgumentNullException(parameter.Name); else return null; } else { value = parameter.Default; return Decode(parameter, value); } } else return Decode(parameter, value); default: throw new ArgumentException(parameter.Style.ToString()); } } else { value = parameter.Fixed; return Decode(parameter, value); } }
//TODO: Method needs to be evaluated //deserialize parameters public void Invoke(NetHttpContext context) { List<object> parameters = new List<object>(); ParameterInfo[] @params = Method.MethodInfo.GetParameters(); Array.ForEach(@params, delegate(ParameterInfo param) { WADLParam[] attributes = WADLParam.GetWADLParams(param); if (param.ParameterType.IsArray) { Type type = Type.GetType(param.ParameterType.AssemblyQualifiedName.Replace("[]", "")); Array array = Array.CreateInstance(type,attributes.Length); IList list = Activator.CreateInstance(typeof(List<>).MakeGenericType(type)) as IList; Resolve(context, list, attributes); list.CopyTo(array, 0); parameters.Add(array); } else { if (attributes.Length == 0) { WADLParam wadlParam = WADLParam.CreateWADLParam(param); parameters.Add(Resolve(context, wadlParam)); } else { parameters.Add(Resolve(context, attributes.Single())); } } }); NetHttpChannelManager instanceToInvoke = Instance; if (Instance.GetInstancingModeAttribute() == InstancingMode.PerCall) { instanceToInvoke = Activator.CreateInstance(Instance.GetType()) as NetHttpChannelManager; } var result = Method.MethodInfo.Invoke(instanceToInvoke, parameters.ToArray()); if (result == null) { WebOperationContext.Current.OutgoingResponse.SetStatusAsNotFound(); WebOperationContext.Current.OutgoingResponse.SuppressEntityBody = true; } else { var outputs = (from representation in Method.Representations select representation).Where<WADLRepresentation>(delegate(WADLRepresentation rep) { return rep.Status == System.Net.HttpStatusCode.OK; }); WADLRepresentation output; if (outputs.Count() == 1) { output = outputs.Single(); context.Response.ContentType = output.ContentType; } else { output = outputs.DefaultIfEmpty(null).SingleOrDefault(o => o.ContentType == context.Response.ContentType); if (output == null) { output = new WADLRepresentation(ContentTypes.unknown); context.Response.ContentType = output.ContentType; } } Encode(context.Response.Buffer, output, result); } }