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

use*_*965 14 c# model-binding asp.net-web-api

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

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

    [Required]
    public string Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

当我打电话时,这很好用/api/values/5?cap=somecap&id=1.

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

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

    [Required]
    public string Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

Pau*_*lor 23

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

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

/api/values/5?cap=somecap&id=1

public IHttpActionResult GetValue([FromUri(Name = "cap")] string capabilities, int id)    
{
}
Run Code Online (Sandbox Code Playgroud)


Seb*_*n K 12

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

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

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

    public string Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

你可能已经知道了.要使它与查询字符串参数一起使用并因此模型绑定器,您必须使用自己的自定义模型绑定器来实际检查和使用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<DataMemberAttribute>()
                                     .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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

public IHttpActionResult GetValue([ModelBinder(typeof(MemberModelBinder))]QueryParameters param)
Run Code Online (Sandbox Code Playgroud)