.NET 4.8 Web API 2:如何将查询字符串sid绑定到SportId属性
.NET 4.8 Web API 实现查询字符串与JsonProperty名称绑定
在.NET 4.8的Web API中,默认FromUri绑定不会识别JsonProperty特性指定的别名,要实现查询字符串sid绑定到SportId属性的需求,你可以通过自定义模型绑定器来实现,具体步骤如下:
1. 自定义模型绑定器
创建继承自IModelBinder的绑定器,利用JSON.NET的契约解析器读取JsonProperty的别名,再从查询字符串中匹配对应参数值:
using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using System.Web.Http.Controllers; using System.Web.Http.ModelBinding; public class JsonPropertyModelBinder : IModelBinder { public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) { if (bindingContext.ModelType.IsClass && bindingContext.ModelType != typeof(string)) { var model = Activator.CreateInstance(bindingContext.ModelType); var contractResolver = new DefaultContractResolver(); var contract = contractResolver.ResolveContract(bindingContext.ModelType) as JsonObjectContract; foreach (var property in contract.Properties) { // 获取JsonProperty指定的别名,无别名则用属性原名 var paramName = property.PropertyName; if (property.AttributeProvider.GetAttributes(typeof(JsonPropertyAttribute), true).FirstOrDefault() is JsonPropertyAttribute jsonAttr) { paramName = jsonAttr.PropertyName; } // 从查询字符串中提取参数值并赋值给模型属性 var valueProviderResult = bindingContext.ValueProvider.GetValue(paramName); if (valueProviderResult != null) { var propertyValue = Convert.ChangeType(valueProviderResult.RawValue, property.PropertyType); bindingContext.ModelType.GetProperty(property.UnderlyingName).SetValue(model, propertyValue); } } bindingContext.Model = model; return true; } return false; } }
2. 创建模型绑定器提供器
实现ModelBinderProvider,让Web API能识别并使用自定义绑定器:
using System.Web.Http.ModelBinding; public class JsonPropertyModelBinderProvider : ModelBinderProvider { public override IModelBinder GetBinder(HttpConfiguration configuration, Type modelType) { // 仅对继承自AppRequest的模型生效,可按需调整过滤逻辑 if (modelType.IsSubclassOf(typeof(AppRequest))) { return new JsonPropertyModelBinder(); } return null; } }
3. 注册绑定器到Web API配置
在WebApiConfig.cs的Register方法中,添加自定义绑定器提供器:
public static class WebApiConfig { public static void Register(HttpConfiguration config) { // 注册自定义模型绑定器提供器 config.Services.Insert(typeof(ModelBinderProvider), 0, new JsonPropertyModelBinderProvider()); // 其他Web API配置 config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); } }
4. 修改Action参数标记
移除原有的[FromUri]特性,全局绑定器会自动处理模型绑定:
public virtual async Task<AppApplicationResponse> Get(AppApplicationRequest request) { return await _appApplicationsService.GetApplication(request); }
可选:局部绑定(无需全局注册)
如果不想全局生效,也可以直接在模型类上标记绑定器:
[ModelBinder(typeof(JsonPropertyModelBinder))] public class AppApplicationRequest : AppRequest { [JsonProperty(PropertyName = "sid")] public SportType? SportId { get; set; } }
完成配置后,查询字符串中的sid参数就会自动绑定到SportId属性,和JSON.NET序列化的别名规则保持一致。
内容的提问来源于stack exchange,提问作者Mike Flynn
相关产品推荐
相关产品推荐

