.NET Framework 4.8下Web API 2如何实现连字符URL参数与C#属性绑定
.NET Framework 4.8 连字符URL参数绑定解决方案
首先需要注意:[JsonProperty]这类JSON序列化特性仅对请求体的JSON参数生效,[FromUri]触发的Query参数绑定默认不走JSON序列化流程,因此无法直接通过该类特性实现别名映射,需要通过自定义模型绑定实现,具体步骤如下:
步骤1:定义参数别名特性
用于标记属性对应的URL参数名:
using System; [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] public class QueryParameterAliasAttribute : Attribute { /// <summary> /// URL中对应的参数名(支持带连字符格式) /// </summary> public string ParameterName { get; } public QueryParameterAliasAttribute(string parameterName) { ParameterName = parameterName; } }
步骤2:实现自定义模型绑定器
处理带别名的参数绑定逻辑:
using System; using System.Reflection; using System.Web.Http.Controllers; using System.Web.Http.ModelBinding; public class AliasQueryModelBinder : IModelBinder { public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) { // 实例化参数类 var modelInstance = Activator.CreateInstance(bindingContext.ModelType); var propertyInfos = bindingContext.ModelType.GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (var property in propertyInfos) { // 优先取别名,没有别名则用属性名匹配 var aliasAttr = property.GetCustomAttribute<QueryParameterAliasAttribute>(); var queryParamName = aliasAttr != null ? aliasAttr.ParameterName : property.Name; // 从Query参数中取值 var valueProviderResult = bindingContext.ValueProvider.GetValue(queryParamName); if (valueProviderResult == null) { continue; } try { // 转换为属性对应的类型 var convertedValue = valueProviderResult.ConvertTo(property.PropertyType); property.SetValue(modelInstance, convertedValue); } catch { // 类型转换错误时可按需添加模型验证错误信息 bindingContext.ModelState.AddModelError(bindingContext.ModelName, $"参数{queryParamName}格式无效"); return false; } } bindingContext.Model = modelInstance; return true; } }
步骤3:修改参数类配置
给参数类指定绑定器,并给需要映射的属性加别名特性:
using System.Web.Http.ModelBinding; [ModelBinder(typeof(AliasQueryModelBinder))] public class GetBooksParameters { [QueryParameterAlias("author-id")] public int? AuthorId { get; set; } // 其他带连字符的参数同理,例如: // [QueryParameterAlias("page-size")] // public int? PageSize { get; set; } }
验证效果
上述修改完成后,原有Controller代码无需调整,以下两种请求均可正常绑定参数:
- 旧格式请求:
/api/books?authorid=3 - 新连字符格式请求:
/api/books?author-id=3
如果需要全局生效不需要给每个参数类加[ModelBinder]特性,可在WebApiConfig.cs的Register方法中添加全局绑定配置:
public static class WebApiConfig { public static void Register(HttpConfiguration config) { // 原有路由等配置保留,添加以下代码 config.BindParameter(typeof(GetBooksParameters), new AliasQueryModelBinder()); // 如果需要全局支持所有参数类的别名绑定,可注册自定义模型绑定提供者,按需扩展即可 } }
内容的提问来源于stack exchange,提问作者Jam
相关产品推荐
相关产品推荐

