日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

ASP.NET Web API中的参数绑定总结

發(fā)布時間:2025/5/22 asp.net 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ASP.NET Web API中的参数绑定总结 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

ASP.NET Web API中的action參數(shù)類型可以分為簡單類型和復(fù)雜類型。

HttpResponseMessage Put(int id, Product item)

id是int類型,是簡單類型,item是Product類型,是復(fù)雜類型。

簡單類型實參值從哪里讀取呢?
--一般從URI中讀取

所謂的簡單類型包括哪些呢?
--int, bool, double, TimeSpan, DateTime, Guid, decimal, string,以及能從字符串轉(zhuǎn)換而來的類型

復(fù)雜類型實參值從哪里讀取呢?
--一般從請求的body中讀取

復(fù)雜類型實參值是否可以從URI中獲取呢?
--可以,按如下

→ 有這樣的一個類

public class Shape {public double Width{get;set;}public double Length{get;set;} }

?

→ 想從URI中獲取,那就加上[FromUri]

public HttpResponseMessage Get([FromUri] Shape shape)

→ 客戶端就可以放在查詢字符串中傳

...api/products/?Width=88&Length=199

簡單類型可以從請求的body中獲取嗎?
--可以。按如下:

→ action方法

public HttpResponseMessage Post([FromBody] string name){...}

→ 前端請求中

Content-Type:applicaiton/json

"hello world"

API服務(wù)端會根據(jù)Content-Type的值選擇合適的媒體類型。

復(fù)雜類型是否可以從uri中的字符串獲取呢?
--可以

api/products/?shape=188,80

如何把uri中查詢字符串中shape的字段值,即以逗號分割的字符串轉(zhuǎn)換成Shape類實例呢?
--使用TypeConverter類

?

[TypeConverter(typeof(ShapeConverter))] public class Shape {public double Width{get;set;}public double Length{get;set;}public static bool TryParse(string s, out Shampe result){result = null;var parts = s.Split(',');if(parts.lenth != 2){return false;}double width, length;if(double.TryParse(parts[0], out width) && double.TryParse(parts[1], out length)){result = new Shape(){Width = width; Length = length};return true;}return false;} }public class ShapeConverter: TypeConverter {public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourcType){if(sourceType == typeof(string)){return true;}return base.CanConvertFrom(context, sourceType);}public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo, object value){if(value is string){Shape shape;if(Shape.TryParse((string)value, out shape)){return shape;}}return base.ConvertFrom(context, culture, value);} }

?

→ 在action不需要[FromUri]

public HttpResponseMessage Get(Shape shape)

→ 客戶端

api/products/?shape=188,80

是否可以通過Model Binder來實現(xiàn)自定義參數(shù)綁定過程呢?
--可以,有IModelBinder接口,提供了BindModel方法

→ 自定義一個Model Binder

?

public class ShapeModelBinder : IModelBinder {private static ConcurrentDictionary<string, Shape> _shapes = new ConcurrentDictionary<string, Shape>(StringComparer.OrdinalIgnoreCase);static ShapeModelBinder(){_shapes["shape1"] = new Shape(){Width= 10, Length = 20};_shapes["shape2"] = new Shape(){Width=12, Length = 22 };}public bool BindModel(HttpActionContext actionContext, ModelBindingContect biningContext){if(bindingContext.ModelType != typeof(Shape)){return false;}ValueProviderResult val = bindingContext.ValueProvider.GetValue(bidingContext.ModelName);if(val == null){return false;}string key = val.RawValue as string;if(key == null){bdingContext.ModelState.AddModelError(bindingContext.ModelName, "值類型錯誤");return false;}Shape shape;if(_shapes.TryGetValue(key, out shape) || Shape.TryParse(key, shape)){bindingContext.Model = result;return true;}bindingContext.ModelState.AddModelError(bindingContext.ModelName, "無法把字符串轉(zhuǎn)換成Shape");return false;} }

?

● 從BindingContext中的ValueProvider屬性獲取到ValueProviderResult
● 從前端查詢字符串中傳來的字符串,被放在ValueProviderResult的RawValue屬性中
● 把字符串轉(zhuǎn)換成Shape實例,最終放在了BindingContext的Model屬性中

→ 使用自定義的Model Binder

可以運用在action中:

public HttpResposneMessage Get([ModelBinder(typeof(ShapeModelBinder))] Shape shape);

可以放在模型上:

[ModelBinder(typeof(Shape))] public class Shape {}

?

也可以放在全局注冊中:

?

public static class WebApiConfig {public static void Register(HttpConfiguraiton config){var provider = new SimpleModelBinderProvider(typeof(Shape), new ShapeModelBinder());config.Services.Insert(typeof(ModelBinderProvider), 0, provider);} }

?

注意:即使在全局注冊,也需要在action中按如下寫:

public HttpResponseMessage Get([ModelBinder] Shape shape);

是否可以通過Value Provider來自定義參數(shù)綁定過程呢?
--可以。

比如,從前端cookie中獲取值,自定義一個Value Provider.

?

public class MyCookieValueProvider : IValueProvider {private Dictionary<string, string> _values;public MyCookieValueProvider(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;} }

?

同時還需要一個ValueProviderFactory.

?

public class MyCookieValueProviderFactory : ValueProviderFactory {public override IValueProvider GetValueProvider(HttpActionContext actionContext){return new MyCookeValueProvider(actionContext);} }

?

最后注冊到全局中。

?

public static void Register(HttpConfiguration config) {config.Services.Add(typeof(ValueProviderFactory), new MyCookieValueProviderFactory()); }

?

還可以把自定義的ValueProvider放在action中。

public HttpResponseMessage Get([ValueProvider(typeof(MyCookieValueProviderFactory))] Shape shape);



是否可以通過HttpParameterBinding實現(xiàn)參數(shù)綁定自定義呢?
--可以。

ModelBinderAttribute繼承于ParameterBindingAttribute.

public abstract class ParameterBindingAttribute : Attribute {public abstract HttpParameterBinding GetBinding(HttpParameterDescriptor parameter); }

?

HttpParameterBinding用來把值綁定到參數(shù)上。

假設(shè),需要從前端請求的if-match和if-none-match字段獲取ETag值。

?

public class ETag {public string Tag{get;set;} }

?

可能從if-match獲取,也可能從if-none-match獲取,來個枚舉。

public enum ETagMatch {IfMatch, IfNoneMatch }

?

自定義HttpParameterBinding。

public class ETagParameterBinding : HttpParameterBinding {ETagMatch _match;public ETagParameterBinding(HttpParameterDescriptor parameter, ETagMatch match) : base(parameter){_match = match;}public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken candellationToken){EntityTagHeaderValue etagHeader = null;switch(_match){case ETagMatch.IfNoneMatch:etagHeader = actionContext.Request.Headers.IfNoneMatch.FirstOrDefault();break;case ETagMatch.IfMatch:etagHeader = actionContext.Request.Headers.IfMatch.FirstOrDefault();break;}ETag etag = null;if(etagHeader != null){etag = new ETag{Tag = etagHeader.Tag};}actionContext.ActionArguemnts[Descriptor.ParameterName] = etag;var tsc = new TaskCompletionSource<object>();tsc.SetResult(null);return tsc.Task;} }

?

可見,所有的action參數(shù)放在了ActionContext的ActionArguments中的。

如何使用自定義的HttpParameterBinding呢?
--通過自定義一個ParameterBindingAttribute特性。

?

public abstract class ETagMatchAttribute : ParameterBindingAttribute {private ETagMatch _match;public ETagMatchAttribute(ETagMatch match){_match = match;}public override HttpParameterBinding GetBinding(HttpParameterDescriptor parameter){if(parameter.ParameterType == typeof(ETag)){return new ETagParameterBinding(parameter, _match);}return parameter.BindAsError("參數(shù)類型不匹配");} }public class IfMatchAttribute : ETageMatchAttribute {public IfMatchAttribute(): base(ETagMatch.IfMatch){} }public class IfNoneMatchAttribute: ETagMatchAttribute {public IfNoneMatchAttribute() : base(ETagMatch.IfNoneMatch){} }

?

再把定義的有關(guān)HttpParameterBinding的特性運用到方法上。

public HttpResponseMessage Get([IfNoneMatch] ETag etag)

還需要在全局注冊:

config.ParameterBindingRules.Add(p => {if(p.ParameterType == typeof(ETag) && p.ActionDescriptor.SupportedHttpMethods.Contains(HttpMethod.Get)){return new ETagParameterBinding(p, ETagMatch.IfNoneMatch);}else{return null;} })

?

總結(jié),本篇體驗了簡單類型和復(fù)雜類型獲取前端數(shù)據(jù)的方式。并通過自定義ValueProvider, ModelBinder, HttpParameterBinding來實現(xiàn)對參數(shù)綁定過程的控制。

?

轉(zhuǎn)載于:https://www.cnblogs.com/darrenji/p/5223938.html

《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的ASP.NET Web API中的参数绑定总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。