コード例 #1
0
        /// <summary>
        /// 从HttpRequest中构造一个参数值
        /// </summary>
        /// <param name="p"></param>
        /// <param name="requst"></param>
        /// <returns></returns>
        public virtual object GetParameter(ParameterInfo p, HttpRequest requst)
        {
            // 参数的第一种取值方式:通过[FromBody]指定,反序列化请求流
            FromBodyAttribute attr = p.GetMyAttribute <FromBodyAttribute>();

            if (attr != null)
            {
                return(FromBodyDeserializeObject(p, requst));
            }


            // 参数的第二种取值方式:通过[FromRequest]指定,从HttpRequest中获取某个属性值
            FromRequestAttribute a2 = p.GetMyAttribute <FromRequestAttribute>();

            if (a2 != null)
            {
                return(FromRequestPropertyGetValue(p, requst));
            }


            // 参数的第三种取值方式:根据参数名,从各种数据集合中获取(Route, QueryString, Form, Headers)
            string value = requst[p.Name];

            if (value != null)
            {
                // 非序列化的参数,允许可空类型
                return(_stringConverter.Instance.ToObject(value, p.ParameterType.GetRealType()));
            }

            // 查找失败
            return(null);
        }
        public ApiServiceCallParameter(ApiServiceCall call, ParameterInfo info)
        {
            this.ServiceCall = call;
            this.Parameter   = info;
            this.FromBody    = info.GetCustomAttribute <FromBodyAttribute>();
            this.FromUri     = info.GetCustomAttribute <FromUriAttribute>();

            String route = call.Route.Template ?? String.Empty;

            if (FromUri != null)
            {
                if (!route.Contains($"{{{Parameter.Name}}}"))
                {
                    FromQueryString = FromUri;
                    FromUri         = null;
                }
            }
            else if (FromBody == null)
            {
                if (route.Contains(Parameter.Name))
                {
                    FromUri = new FromUriAttribute();
                }
                else
                {
                    FromBody = new FromBodyAttribute();
                }
            }
        }
コード例 #3
0
        public async Task <IActionResult> GetSpotifyUser(FromBodyAttribute authCode, string code)
        {
            var authToken = GetAuthToken(code);

            var userResponse = await SpotifyUser.GetCurrentUserProfile(authToken);

            return(Ok(userResponse));
        }
コード例 #4
0
        public async Task <IActionResult> GetSpotifyUser(FromBodyAttribute authCode, string code)
        {
            var authToken = HttpHelper.Post("https://accounts.spotify.com/api/token", code);

            var userResponse = await SpotifyUser.GetCurrentUserProfile(authToken);

            await _dashboardHub.Clients.All.InvokeAsync("TestSend", "Hello From The Hub Server!!");

            return(Ok(userResponse));
        }
コード例 #5
0
        private static ParameterSourceAttribute GetDefaultParameterSource(ParameterInfo parameter)
        {
            if ((typeof(Guid) == parameter.ParameterType) || (typeof(DateTime) == parameter.ParameterType) ||
                ((parameter.ParameterType.IsIdentity()) && (PopularIdentifierPropertyNames.Contains(parameter.Name, StringComparer.OrdinalIgnoreCase))))
            {
                return(FromUrlAttribute.For(parameter));
            }

            if ((!parameter.ParameterType.IsValueType) && (typeof(string) != parameter.ParameterType) &&
                (!((System.TypeExtensions.IsEnumerable(parameter.ParameterType)) && (parameter.ParameterType.GetItemType().IsNumber()))))
            {
                return(FromBodyAttribute.For(parameter));
            }

            return(FromQueryStringAttribute.For(parameter));
        }
コード例 #6
0
        private void Process_MethodParams(MethodInfo mInfo, ref ApiMethodObj m)
        {
            //m.Attributes = attribs.Select(a => a.GetType().Name.Replace("Attribute", "")).ToList();

            var allParams = mInfo.GetParameters();

            if (allParams.Length == 1)
            {
                var p = GenerateApiMethodParamObj(allParams.First());

                FromBodyAttribute fromBodyAttr = (FromBodyAttribute)Attribute.GetCustomAttribute(allParams.First(), typeof(FromBodyAttribute));

                //if it is exactly one param && it has the attribute or it is complex type param then by default it is FromBody
                if (fromBodyAttr != null || !IsSimpleType(allParams.First().ParameterType))
                {
                    p.IsFromBody = true;
                }

                m.ParameterArray.Add(p);
            }
            else
            {
                //only one FromBody will receive the body params even if the attribute is put for multiple params.
                //src: https://stackoverflow.com/questions/24874490/pass-multiple-complex-objects-to-a-post-put-web-api-method
                bool isFromBodyAlreadySet = false;

                foreach (var pInfo in mInfo.GetParameters().OrderBy(p => p.Position))
                {
                    var p = GenerateApiMethodParamObj(pInfo);

                    FromBodyAttribute fromBodyAttr = (FromBodyAttribute)Attribute.GetCustomAttribute(pInfo, typeof(FromBodyAttribute));

                    if (!isFromBodyAlreadySet && fromBodyAttr != null)
                    {
                        p.IsFromBody = true;
                    }

                    m.ParameterArray.Add(p);
                }
            }
        }
コード例 #7
0
        private static OperationInfo <Verb> CreateOperation(MethodInfo method, Verb verb)
        {
            string queryString             = String.Empty;
            string uriTemplate             = null;
            IList <ArgumentInfo> arguments = new List <ArgumentInfo>();

            foreach (var parameter in method.GetParameters())
            {
                if (parameter.IsOut)
                {
                    continue;
                }

                string parameterTemplate        = null;
                ParameterSourceAttribute source = null;
                if (parameter.ParameterType == typeof(Guid))
                {
                    source       = FromUrlAttribute.For(parameter);
                    uriTemplate += (parameterTemplate = "/" + parameter.Name + "/{?value}");
                }
                else if (parameter.ParameterType.IsValueType)
                {
                    source       = FromQueryStringAttribute.For(parameter);
                    queryString += (parameterTemplate = "&" + parameter.Name + "={?value}");
                }
                else if (!parameter.ParameterType.IsValueType)
                {
                    source = FromBodyAttribute.For(parameter);
                }

                arguments.Add(new ArgumentInfo(parameter, source, parameterTemplate, (parameterTemplate != null ? parameter.Name : null)));
            }

            if (queryString.Length > 0)
            {
                uriTemplate += "?" + queryString.Substring(1);
            }

            return(new OperationInfo <Verb>(method, (HttpUrl)UrlParser.Parse("/"), uriTemplate, new Regex(".*"), verb, arguments.ToArray()).WithSecurityDetailsFrom(method));
        }
コード例 #8
0
        private object[] GetMultiObjectsFormString(string input, ActionDescription action, HttpContext context)
        {
            JObject jsonObj = JObject.Parse(input);

            DefaultJsonSerializer  jsonnet  = new DefaultJsonSerializer();
            JsonSerializerSettings settings = jsonnet.GetJsonSerializerSettings(false);

            Newtonsoft.Json.JsonSerializer jsonSerializer
                = Newtonsoft.Json.JsonSerializer.CreateDefault(settings);


            object[] parameters = new object[action.Parameters.Length];

            for (int i = 0; i < parameters.Length; i++)
            {
                FromBodyAttribute bodyAttr = action.Parameters[i].GetMyAttribute <FromBodyAttribute>(false);
                if (bodyAttr != null)
                {
                    // 当前参数需要从整体请求体中反序列化得到参数值
                    parameters[i] = GetObjectFromString(input, action);
                }
                else
                {
                    //尝试从JSON中获取一个片段,用这个片段来构造参数值
                    JToken childObj = jsonObj.GetValue(action.Parameters[i].Name, StringComparison.OrdinalIgnoreCase);
                    if (childObj != null)
                    {
                        Type pType = action.Parameters[i].ParameterType;
                        parameters[i] = childObj.ToObject(pType, jsonSerializer);
                    }
                    else
                    {
                        // 再次尝试从HTTP上下文中获取
                        parameters[i] = GetParameterFromHttp(context, action.Parameters[i]);
                    }
                }
            }

            return(parameters);
        }
コード例 #9
0
        // Determine how a single parameter will get bound.
        // This is all sync. We don't need to actually read the body just to determine that we'll bind to the body.
        protected virtual HttpParameterBinding GetParameterBinding(
            HttpParameterDescriptor parameter
            )
        {
            // Attribute has the highest precedence
            // Presence of a model binder attribute overrides.
            ParameterBindingAttribute attr = parameter.ParameterBinderAttribute;

            if (attr != null)
            {
                return(attr.GetBinding(parameter));
            }

            // No attribute, so lookup in global map.
            ParameterBindingRulesCollection pb = parameter.Configuration.ParameterBindingRules;

            if (pb != null)
            {
                HttpParameterBinding binding = pb.LookupBinding(parameter);
                if (binding != null)
                {
                    return(binding);
                }
            }

            // Not explicitly specified in global map or attribute.
            // Use a default policy to determine it. These are catch-all policies.
            Type type = parameter.ParameterType;

            if (TypeHelper.CanConvertFromString(type))
            {
                // For simple types, the default is to look in URI. Exactly as if the parameter had a [FromUri] attribute.
                return(parameter.BindWithAttribute(new FromUriAttribute()));
            }

            // Fallback. Must be a complex type. Default is to look in body. Exactly as if this type had a [FromBody] attribute.
            attr = new FromBodyAttribute();
            return(attr.GetBinding(parameter));
        }
コード例 #10
0
        private static ParameterSourceAttribute GetParameterTarget(this ParameterInfo parameter)
        {
            var explicitSetting = parameter.GetCustomAttribute <ParameterSourceAttribute>(true);

            if (explicitSetting != null)
            {
                return(explicitSetting);
            }

            if ((typeof(Guid) == parameter.ParameterType) || (typeof(DateTime) == parameter.ParameterType) ||
                ((IsIdentity(parameter.ParameterType)) &&
                 (PopularIdentifierPropertyNames.Contains(parameter.Name, StringComparer.OrdinalIgnoreCase))))
            {
                return(FromUrlAttribute.For(parameter));
            }

            if ((!parameter.ParameterType.IsValueType) && (typeof(string) != parameter.ParameterType) &&
                (!((System.TypeExtensions.IsEnumerable(parameter.ParameterType)) && (IsNumber(parameter.ParameterType.GetItemType())))))
            {
                return(FromBodyAttribute.For(parameter));
            }

            return(FromQueryStringAttribute.For(parameter));
        }
コード例 #11
0
        // Determine how a single parameter will get bound. 
        // This is all sync. We don't need to actually read the body just to determine that we'll bind to the body.         
        protected virtual HttpParameterBinding GetParameterBinding(HttpParameterDescriptor parameter)
        {
            // Attribute has the highest precedence
            // Presence of a model binder attribute overrides.
            ParameterBindingAttribute attr = parameter.ParameterBinderAttribute;
            if (attr != null)
            {
                return attr.GetBinding(parameter);
            }

            // No attribute, so lookup in global map.
            ParameterBindingRulesCollection pb = parameter.Configuration.ParameterBindingRules;
            if (pb != null)
            {
                HttpParameterBinding binding = pb.LookupBinding(parameter);
                if (binding != null)
                {
                    return binding;
                }
            }

            // Not explicitly specified in global map or attribute.
            // Use a default policy to determine it. These are catch-all policies. 
            Type type = parameter.ParameterType;
            if (TypeHelper.IsSimpleUnderlyingType(type) || TypeHelper.HasStringConverter(type))
            {
                // For simple types, the default is to look in URI. Exactly as if the parameter had a [FromUri] attribute.
                return parameter.BindWithAttribute(new FromUriAttribute());
            }

            // Fallback. Must be a complex type. Default is to look in body. Exactly as if this type had a [FromBody] attribute.
            attr = new FromBodyAttribute();
            return attr.GetBinding(parameter);
        }
コード例 #12
0
        Service ProcessService(Type type)
        {
            bool enabled = true;

            Service service = new Service()
            {
                Name = type.Name.Replace("Api", "").Replace("Controller", ""),
            };

            DiscoveryAttribute discoveryAttr = type.GetCustomAttribute <DiscoveryAttribute>(true);

            if (discoveryAttr != null)
            {
                service.DiscoveryName = discoveryAttr.DiscoveryName;
                service.Dependency    = discoveryAttr.Dependency;
                enabled = discoveryAttr.Enabled;
            }

            if (enabled)
            {
                string hostAddress = _HostAddress + (_HostAddress.EndsWith("/") ? "" : "/");
                string routePrefix = string.Empty;

                RouteAttribute routePrefixAttr = type.GetCustomAttribute <RouteAttribute>(true);
                if (routePrefixAttr != null)
                {
                    routePrefix = routePrefixAttr.Template + (routePrefixAttr.Template.EndsWith("/") ? "" : "/");
                }

                List <Operation> operations = new List <Operation>();

                MethodInfo[] methods = type.GetMethods();
                foreach (MethodInfo methodInfo in methods)
                {
                    string method        = string.Empty;
                    string route         = string.Empty;
                    string discoveryName = string.Empty;
                    string dependency    = string.Empty;

                    // public method only declared in this class
                    if (methodInfo.IsPublic && methodInfo.DeclaringType.FullName == type.FullName)
                    {
                        object[] methodAttrs = methodInfo.GetCustomAttributes(false);
                        foreach (object methodAttr in methodAttrs)
                        {
                            Type methodAttrType = methodAttr.GetType();

                            Type[] httpAttrInterfaces = methodAttrType.GetInterfaces();
                            foreach (Type interfaceType in httpAttrInterfaces)
                            {
                                if (interfaceType.Equals(typeof(IActionHttpMethodProvider)))
                                {
                                    // found HTTP attribute
                                    method = methodAttrType.Name.Replace("Http", "").Replace("Attribute", "").ToUpper();
                                    route  = ((HttpMethodAttribute)methodAttr).Template;
                                    break;
                                }
                            }

                            if (methodAttrType.Equals(typeof(RouteAttribute)))
                            {
                                // process route and method arguments - Route attribute template overrides very attribute template
                                RouteAttribute routeAttr = methodAttr as RouteAttribute;
                                if (routeAttr != null)
                                {
                                    route = routeAttr.Template;
                                }
                            }

                            //if (methodInfo.Name == "Calc3")
                            //    System.Diagnostics.Debugger.Break();

                            if (!string.IsNullOrWhiteSpace(route))
                            {
                                ParameterInfo[] arguments = methodInfo.GetParameters();
                                if (arguments != null)
                                {
                                    List <ParameterInfo> parameters        = new List <ParameterInfo>();
                                    ParameterInfo        fromBodyParameter = null;
                                    foreach (ParameterInfo parameterInfo in arguments)
                                    {
                                        if (!parameterInfo.ParameterType.Equals(typeof(HttpRequestMessage)))
                                        {
                                            FromBodyAttribute fromBodyAttr = parameterInfo.GetCustomAttribute <FromBodyAttribute>(false);
                                            FromFormAttribute fromFormAttr = parameterInfo.GetCustomAttribute <FromFormAttribute>(false);
                                            if (fromBodyAttr == null && fromFormAttr == null)
                                            {
                                                // ensure parameter name is not already in the route
                                                if (route.IndexOf("{" + parameterInfo.Name + "}") == -1)
                                                {
                                                    // parameter is in method signature but not in route
                                                    parameters.Add(parameterInfo);
                                                }
                                            }
                                            else
                                            {
                                                fromBodyParameter = parameterInfo;
                                            }
                                        }
                                    }

                                    if (parameters.Count > 0)
                                    {
                                        int index = 0;
                                        foreach (ParameterInfo parameterInfo in parameters)
                                        {
                                            route += (index == 0 ? "?" : "&") + parameterInfo.Name + "={" + parameterInfo.Name + "}";
                                            index++;
                                        }
                                    }
                                }
                            }

                            if (methodAttrType.Equals(typeof(DiscoveryAttribute)))
                            {
                                DiscoveryAttribute opDiscAttr = methodAttr as DiscoveryAttribute;
                                if (opDiscAttr != null)
                                {
                                    discoveryName = opDiscAttr.DiscoveryName;
                                    dependency    = opDiscAttr.Dependency;
                                }
                            }
                        }

                        if (method == string.Empty)
                        {
                            method = "GET";
                        }

                        if (route.StartsWith("~/"))
                        {
                            route = route.Substring(2);
                        }
                        else
                        {
                            route = routePrefix + route;
                        }

                        Operation operation = new Operation()
                        {
                            Name          = methodInfo.Name,
                            Method        = method,
                            Route         = route,
                            DiscoveryName = discoveryName,
                            Dependency    = dependency
                        };

                        // if no discovery nane found, make one out of route
                        if (string.IsNullOrWhiteSpace(operation.DiscoveryName) && !string.IsNullOrWhiteSpace(operation.Route))
                        {
                            Uri    uri       = new Uri(this._HostAddress + operation.Route);
                            string localPath = uri.LocalPath;
                            if (localPath.IndexOf("?") > -1)
                            {
                                operation.DiscoveryName = localPath.Substring(1, uri.LocalPath.IndexOf("?") - 1);
                            }
                            else if (localPath.IndexOf("{") > -1)
                            {
                                operation.DiscoveryName = localPath.Substring(1, uri.LocalPath.IndexOf("{") - 1);
                            }
                            else
                            {
                                operation.DiscoveryName = localPath;
                            }

                            if (operation.DiscoveryName.StartsWith("/"))
                            {
                                operation.DiscoveryName = operation.DiscoveryName.Substring(1);
                            }

                            if (operation.DiscoveryName.EndsWith("/"))
                            {
                                operation.DiscoveryName = operation.DiscoveryName.Substring(0, operation.DiscoveryName.Length - 1);
                            }
                        }

                        operations.Add(operation);
                    }
                }

                service.Operations = operations;
            }
            else
            {
                service = null;
            }

            return(service);
        }
コード例 #13
0
        private object[] GetMultiObjectsFormRequest(HttpContext context, ActionDescription action)
        {
            HttpRequest request = context.Request;
            string      xml     = request.ReadInputStream();

            XmlDocument doc = new XmlDocument();

            doc.LoadXml(xml);

            XmlNode root = doc.LastChild;

            //if( root.ChildNodes.Count != action.Parameters.Length )
            //    throw new ArgumentException("客户端提交的数据项与服务端的参数项的数量不匹配。");

            object[] parameters = new object[action.Parameters.Length];
            LazyObject <ModelBuilder> builder = new LazyObject <ModelBuilder>();

            for (int i = 0; i < parameters.Length; i++)
            {
                FromBodyAttribute bodyAttr = action.Parameters[i].GetMyAttribute <FromBodyAttribute>(false);
                if (bodyAttr != null)
                {
                    // 当前参数需要从整体请求体中反序列化得到参数值
                    parameters[i] = GetObjectFromRequest(context, action);
                }
                else
                {
                    string  name = action.Parameters[i].Name;
                    XmlNode node = (from n in root.ChildNodes.Cast <XmlNode>()
                                    where string.Compare(n.Name, name, StringComparison.OrdinalIgnoreCase) == 0
                                    select n).FirstOrDefault();

                    if (node != null)
                    {
                        try {
                            object parameter = null;
                            Type   destType  = action.Parameters[i].ParameterType.GetRealType();

                            if (destType.IsSupportableType())                                   // 如果是简单类型,就不需要反序列化
                            {
                                parameter = builder.Instance.StringToObject(node.InnerText, destType);
                            }
                            else
                            {
                                // 复杂类型的参数,就使用反序列化
                                parameter = XmlDeserialize(node.OuterXml, destType, request.ContentEncoding);
                            }

                            parameters[i] = parameter;
                        }
                        catch (Exception ex) {
                            throw new InvalidCastException("数据转换失败,当前参数名:" + name, ex);
                        }
                    }
                    else
                    {
                        // 再次尝试从HTTP上下文中获取
                        parameters[i] = GetParameterFromHttp(context, action.Parameters[i]);
                    }
                }
            }

            return(parameters);
        }
コード例 #14
0
        public void Setup()
        {
            Mock <IDefaultValueRelationSelector> defaultSourceSelector = new Mock <IDefaultValueRelationSelector>(MockBehavior.Strict);

            defaultSourceSelector.Setup(instance => instance.ProvideDefault(It.IsAny <ParameterInfo>(), It.IsAny <Verb>()))
            .Returns <ParameterInfo, Verb>((parameter, verb) =>
                                           (parameter.ParameterType == typeof(int) ? (ParameterSourceAttribute)FromUrlAttribute.For(parameter) : FromBodyAttribute.For(parameter)));
            defaultSourceSelector.Setup(instance => instance.ProvideDefault(It.IsAny <ParameterInfo>()))
            .Returns <ParameterInfo>(parameter => new ToBodyAttribute());
            _builder = new ControllerDescriptionBuilder <CrudController>(defaultSourceSelector.Object);
        }
コード例 #15
0
 public IHttpActionResult createQuiz(FromBodyAttribute fromBody)
 {
 }