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
复制代码

完了。。。。。

posted @   indexlang  阅读(1271)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示