• asp.net web api参数


    翻译自:http://www.c-sharpcorner.com/article/parameter-binding-in-asp-net-web-api/

    主要自己学习下,说是翻译,主要是把文章的意思记录下,下面进入正题

    web api 对于一般的基本类型(primitive type)(bool,int ,double,log,timespan,datetime,guid,string)直接从url读取,对于复杂类型,web api从请求的body获取,需要使用media type。

    对于这个api:

    Public HttpResponseMessage Put(int id, Employee employee)  
    {  
    …  
    …  
    }  
    View Code

    web api 从url中获取id类型,从body中获取employee类型。

    当然这是默认情况,我们可以强制web api通过fromurl和frombody特性从url或者从body获取。

    fromuri 特性

    public class TestData  
    {  
        public string Name   
        {  
            get;  
            set;  
        }  
        public int Id   
        {  
            get;  
            set;  
        }  
    }  
    View Code
    public HttpResponseMessage Get([FromUri] TestData data)   
    {……  
        return Request.CreateResponse(HttpStatusCode.OK, true);  
    }  
    View Code

    这样就可以强制从url获取参数,web api生成TestData类。url:http://localhost:24367/api/Employee?Name=Jignesh&Id=10

    可以测试下,这样没任何问题。

    fromBody 特性

    [HttpPost]  
    public HttpResponseMessage Post([FromBody] string name)  
    {  
        ……  
        return Request.CreateResponse(HttpStatusCode.OK, true);  
    }  
    View Code

    对于这个api,调用时要设置content type:“application/json”

    这样设置可以成功调用。

    这样就不成功了,web api 支持json string,不支持json 对象,因此只允许在body中有一个参数。

    Type converters


    可以使用类型转换的方法,将请求的数据按字符串处理,处理过程如下:

    namespace WebAPITest  
    {  
        using System;  
        using System.ComponentModel;  
        using System.Globalization;  
        public class TestTypeConverter: TypeConverter  
        {  
            public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)  
            {  
                if (sourceType == typeof(string))  
                {  
                    returntrue;  
                }  
                returnbase.CanConvertFrom(context, sourceType);  
            }  
      
            public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)  
            {  
                if (value is string)  
                {  
                    TestData data;  
                    if (TestData.TryParse((string) value, out data))  
                    {  
                        return data;  
                    }  
                }  
                return base.ConvertFrom(context, culture, value);  
            }  
        }  
    }  
    View Code
    namespaceWebAPITest   
    {  
        using System.ComponentModel;  
        [TypeConverter(typeof(TestTypeConverter))]  
        public class TestData  
        {  
            public string Name  
            {  
                get;  
                set;  
            }  
            public int Id  
            {  
                get;  
                set;  
            }  
      
            public static bool TryParse(string s, outTestData result)  
            {  
                result = null;  
      
                var parts = s.Split(',');  
                if (parts.Length != 2)  
                {  
                    return false;  
                }  
      
                int id;  
                string name = parts[1];  
                if (int.TryParse(parts[0], out id))  
                {  
                    result = newTestData()  
                    {  
                        Id = id, Name = name  
                    };  
                    return true;  
                }  
                return false;  
            }  
        }  
    }  
    View Code

    这样就可以不用写from url这样调用: http://localhost:24367/api/Employee?data=10,jignesh%20trivedi

    public HttpResponseMessage Get(TestData data)  
    {  
        ……  
        return Request.CreateResponse(HttpStatusCode.OK, true);  
    }  
    View Code

    Model Binder

    另外一种处理参数的方法,实现IModelBinder 接口,只用实现一个方法BindModel,下面的代码从路由中读取raw data,将其转换成TestData,实例是一个简单类型转换,当然Model binder不限于简单类型:

    namespace WebAPITest  
    {  
        using System;  
        using System.Web.Http.Controllers;  
        using System.Web.Http.ModelBinding;  
        using System.Web.Http.ValueProviders;  
        public class CustomModelBinder: IModelBinder  
        {  
            static CustomModelBinder()  
            {  
      
            }  
      
            public bool BindModel(HttpActionContextactionContext, ModelBindingContextbindingContext)  
            {  
                if (bindingContext.ModelType != typeof(TestData))  
                {  
                    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");  
                    returnfalse;  
                }  
                TestData result = newTestData();  
      
                var data = key.Split(newchar[]  
                {  
                    ','  
                });  
                if (data.Length > 1)  
                {  
                    result.Id = Convert.ToInt32(data[0]);  
                    result.Name = data[1];  
                    bindingContext.Model = result;  
                    return true;  
                }  
      
                bindingContext.ModelState.AddModelError(  
                    bindingContext.ModelName, "Cannot convert value to TestData");  
                return false;  
            }  
        }  
    }  
    View Code

    另外需要注册这个binder,我们需要在configuration中生成一个 model-binder provider 。这里使用自带的provider:SimpleModelBinderProvider

    namespace WebAPITest  
    {  
        using System.Web.Http;  
        using System.Web.Http.ModelBinding;  
        using System.Web.Http.ModelBinding.Binders;  
        public static class WebApiConfig  
        {  
            public static void Register(HttpConfigurationconfig)  
            {  
                var provider = newSimpleModelBinderProvider(  
                    typeof(TestData), newCustomModelBinder());  
                config.Services.Insert(typeof(ModelBinderProvider), 0, provider);  
      
                config.MapHttpAttributeRoutes();  
      
                config.Routes.MapHttpRoute(  
                    name: "DefaultApi",  
                    routeTemplate: "api/{controller}/{id}",  
                    defaults: new  
                    {  
                        id = RouteParameter.Optional  
                    });  
            }  
        }  
    }  
    View Code

    调用这个url:URI: http://localhost:24367/api/Employee?data=10,jignesh%20trivedi,有多种方法使用这个Model binder。在参数上使用特性:

    public HttpResponseMessage Get([ModelBinder(typeof(CustomModelBinder))] TestData data)  
      
    {  
        ……  
        return Request.CreateResponse(HttpStatusCode.OK, true);  
    }  
    View Code

    另外可以在类上使用这个特性:

    [ModelBinder(typeof(CustomModelBinder))]  
    public class TestData   
    {  
        //......  
    }  
    View Code

    完了。。。。。

  • 相关阅读:
    mysql 45讲 索引的使用 09-11
    mysql 45讲 相关锁的概念 06-08
    mysql 45讲 深入浅出索引04-05
    mysql 45讲 概览 01-03
    AQS源码解析第二回
    面试相关-怎么实现限流功能
    人工智能必备数学基础:线性代数基础(2)
    Elasticsearch问题总结和解决方法
    spring boot中打印所有日志
    Java中Stream流里面的findFirst()和findAny()区别
  • 原文地址:https://www.cnblogs.com/indexlang/p/5731478.html
Copyright © 2020-2023  润新知