zoukankan      html  css  js  c++  java
  • web api 参数绑定

    简单类型参数: url读取(string,bool,int...)

    复杂类型参数:从message body用media-type formatter 读取

    url读取route data(路由解析uri的时候得到)和URI query string

    强制复杂类型从uri获取

    public class GeoPoint
    {
        public double Latitude { get; set; } 
        public double Longitude { get; set; }
    }
    
    public ValuesController : ApiController
    {
        public HttpResponseMessage Get([FromUri] GeoPoint location) { ... }
    }

    http://localhost/api/values/?Latitude=47.678558&Longitude=-122.130989

    强制简单类型从request body获取([FromBody]时webapi 会用Content-Type选择一个media type formatter)

    public HttpResponseMessage Post([FromBody] string name) { ... } //只能用于一个参数的情况


    POST http://localhost:5076/api/values HTTP/1.1
    User-Agent: Fiddler
    Host: localhost:5076
    Content-Type: application/json
    Content-Length: 7

    "Alice"

    类型转换(实现类型转换后,会当做简单类型尝试从uri获取)

    [TypeConverter(typeof(GeoPointConverter))]
    public class GeoPoint
    {
        public double Latitude { get; set; } 
        public double Longitude { get; set; }
    
        public static bool TryParse(string s, out GeoPoint result)
        {
            result = null;
    
            var parts = s.Split(',');
            if (parts.Length != 2)
            {
                return false;
            }
    
            double latitude, longitude;
            if (double.TryParse(parts[0], out latitude) &&
                double.TryParse(parts[1], out longitude))
            {
                result = new GeoPoint() { Longitude = longitude, Latitude = latitude };
                return true;
            }
            return false;
        }
    }
    
    class GeoPointConverter : TypeConverter
    {
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(string))
            {
                return true;
            }
            return base.CanConvertFrom(context, sourceType);
        }
    
        public override object ConvertFrom(ITypeDescriptorContext context, 
            CultureInfo culture, object value)
        {
            if (value is string)
            {
                GeoPoint point;
                if (GeoPoint.TryParse((string)value, out point))
                {
                    return point;
                }
            }
            return base.ConvertFrom(context, culture, value);
        }
    }
    
    
    public HttpResponseMessage Get(GeoPoint location) { ... }
    
    http://localhost/api/values/?location=47.678558,-122.130989

    Model Binders

    public class GeoPointModelBinder : IModelBinder
    {
        // List of known locations.
        private static ConcurrentDictionary<string, GeoPoint> _locations
            = new ConcurrentDictionary<string, GeoPoint>(StringComparer.OrdinalIgnoreCase);
    
        static GeoPointModelBinder()
        {
            _locations["redmond"] = new GeoPoint() { Latitude = 47.67856, Longitude = -122.131 };
            _locations["paris"] = new GeoPoint() { Latitude = 48.856930, Longitude = 2.3412 };
            _locations["tokyo"] = new GeoPoint() { Latitude = 35.683208, Longitude = 139.80894 };
        }
    
        public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
        {
            if (bindingContext.ModelType != typeof(GeoPoint))
            {
                return false;
            }
    
            ValueProviderResult val = bindingContext.ValueProvider.GetValue(
                bindingContext.ModelName);
            if (val == null)
            {
                return false;
            }
    
            string key = val.RawValue as string;
            if (key == null)
            {
                bindingContext.ModelState.AddModelError(
                    bindingContext.ModelName, "Wrong value type");
                return false;
            }
    
            GeoPoint result;
            if (_locations.TryGetValue(key, out result) || GeoPoint.TryParse(key, out result))
            {
                bindingContext.Model = result;
                return true;
            }
    
            bindingContext.ModelState.AddModelError(
                bindingContext.ModelName, "Cannot convert value to Location");
            return false;
        }
    }

    使用

    //1
    public HttpResponseMessage Get([ModelBinder(typeof(GeoPointModelBinder))] GeoPoint location)
    
    
    //2
    [ModelBinder(typeof(GeoPointModelBinder))]
    public class GeoPoint
    {
        // ....
    }
    
    
    //3
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            var provider = new SimpleModelBinderProvider(
                typeof(GeoPoint), new GeoPointModelBinder());
            config.Services.Insert(typeof(ModelBinderProvider), 0, provider);
    
            // ...
        }
    }
    public HttpResponseMessage Get([ModelBinder] GeoPoint location) { ... }

    value provider(解析参数返回字典对象)

    例:

    http://localhost/api/values/1?location=48,-122

    会解析为字典

    • id = "1"
    • location = "48,122"

    id,location对应ModelBindingContext.ModelName

    "1","48,122" RawValue如果被正确转换会被设置到ModelBindingContext.Model

    public class CookieValueProvider : IValueProvider
    {
        private Dictionary<string, string> _values;
    
        public CookieValueProvider(HttpActionContext actionContext)
        {
            if (actionContext == null)
            {
                throw new ArgumentNullException("actionContext");
            }
    
            _values = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
            foreach (var cookie in actionContext.Request.Headers.GetCookies())
            {
                foreach (CookieState state in cookie.Cookies)
                {
                    _values[state.Name] = state.Value;
                }
            }
        }
    
        public bool ContainsPrefix(string prefix)
        {
            return _values.Keys.Contains(prefix);
        }
    
        public ValueProviderResult GetValue(string key)
        {
            string value;
            if (_values.TryGetValue(key, out value))
            {
                return new ValueProviderResult(value, value, CultureInfo.InvariantCulture);
            }
            return null;
        }
    }

    使用(查找值时会使用所有注册的value provider查找,得到第一个返回的值)

    public class CookieValueProviderFactory : ValueProviderFactory
    {
        public override IValueProvider GetValueProvider(HttpActionContext actionContext)
        {
            return new CookieValueProvider(actionContext);
        }
    }
    
    public static void Register(HttpConfiguration config)
    {
        config.Services.Add(typeof(ValueProviderFactory), new CookieValueProviderFactory());
    
        // ...
    }
    
    // 不使用其他value provider
    public HttpResponseMessage Get(
        [ValueProvider(typeof(CookieValueProviderFactory))] GeoPoint location)

    HttpParameterBinding

    url:http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api

  • 相关阅读:
    Python Scrapy 爬虫入门
    Python Requests 高级用法
    Python Requests库快速入门
    linux 高并发事件触发处理 — epoll
    初识Python爬妹子图片
    android 使用gradle实现资源自动拷贝
    Android Studio Cmake使用 (附带demo)
    JNI 学习笔记
    Cmake 常见命令说明
    mybatis逆向工程生成代码
  • 原文地址:https://www.cnblogs.com/yfann/p/4712324.html
Copyright © 2011-2022 走看看