更改参数名称Web Api模型绑定

我正在使用Web API模型绑定来解析URL中的查询参数。 例如,这是一个模型类:

public class QueryParameters { [Required] public string Cap { get; set; } [Required] public string Id { get; set; } } 

当我调用/api/values/5?cap=somecap&id=1类的东西时这很好用/api/values/5?cap=somecap&id=1

有什么方法可以在模型类中更改属性的名称,但保持查询参数名称相同 – 例如:

 public class QueryParameters { [Required] public string Capability { get; set; } [Required] public string Id { get; set; } } 

我认为将[Display(Name="cap")]Capability属性会起作用,但事实并非如此。 我应该使用某种类型的数据注释吗?

控制器将有一个如下所示的方法:

 public IHttpActionResult GetValue([FromUri]QueryParameters param) { // Do Something with param.Cap and param.id } 

您可以使用FromUri绑定属性的Name属性将查询字符串参数与方法参数使用不同的名称。

如果传递简单参数而不是QueryParameters类型,则可以绑定如下值:

 /api/values/5?cap=somecap&id=1 public IHttpActionResult GetValue([FromUri(Name = "cap")] string capabilities, int id) { } 

Web API使用与ASP.NET MVC不同的模型绑定机制。 它使用格式化程序在主体中传递的数据和模型绑定器中查询字符串中传递的数据(如您的情况)。 Formatters遵循其他元数据属性,而模型绑定器则不然。

因此,如果您在消息体中传递模型而不是查询字符串,则可以按如下方式对数据进行注释,它可以工作:

 public class QueryParameters { [DataMember(Name="Cap")] public string Capability { get; set; } public string Id { get; set; } } 

你可能已经知道了。 要使它与查询字符串参数一起使用并因此模型绑定器,您必须使用自己的自定义模型绑定器来实际检查和使用DataMember属性。

下面这段代码可以解决问题(尽管它远非生产质量):

 public class MemberModelBinder : IModelBinder { public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) { var model = Activator.CreateInstance(bindingContext.ModelType); foreach (var prop in bindingContext.PropertyMetadata) { // Retrieving attribute var attr = bindingContext.ModelType.GetProperty(prop.Key) .GetCustomAttributes(false) .OfType() .FirstOrDefault(); // Overwriting name if attribute present var qsParam = (attr != null) ? attr.Name : prop.Key; // Setting value of model property based on query string value var value = bindingContext.ValueProvider.GetValue(qsParam).AttemptedValue; var property = bindingContext.ModelType.GetProperty(prop.Key); property.SetValue(model, value); } bindingContext.Model = model; return true; } } 

您还需要在控制器方法中指明要使用此模型绑定器:

 public IHttpActionResult GetValue([ModelBinder(typeof(MemberModelBinder))]QueryParameters param) 

我花了几个小时研究一个针对同一个问题的强大解决方案,当一个单行工具就可以解决这个问题:

 myModel.Capability = HttpContext.Current.Request["cap"]; 

我刚刚遇到这个并在我的参数类中使用了一个getter来返回绑定属性。

所以在你的例子中:

 public class QueryParameters { public string cap {get; set;} public string Capability { get { return cap; } } public string Id { get; set; } } 

现在,在Controller中,您可以引用Capability属性。

 public IHttpActionResult GetValue([FromUri]QueryParameters param) { // Do Something with param.Capability, // except assign it a new value because it's only a getter } 

当然,如果您对param对象使用reflection或序列化它,则将包含cap属性。 不知道为什么有人会需要使用查询参数。