2014-10-28 67 views
10

我正在使用Web API模型綁定從URL解析查詢參數。例如,這裏是一個模型類:更改參數名稱Web Api模型綁定

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

    [Required] 
    public string Id { get; set; } 
} 

這個工作正常,當我打電話像/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 
} 

回答

7

的Web API使用的模型比ASP.NET MVC結合有點不同的機制。它使用正文和模型綁定器中傳遞的數據的格式化程序來傳遞查詢字符串中的數據(與您的情況相同)。格式化程序尊重額外的元數據屬性,而模型活頁夾則不會。

所以,如果你傳遞郵件正文而不是查詢字符串你的模型,你可以註釋你的數據如下,它的工作:

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<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; 
    } 
} 

您還需要在你的控制器方法來指示要使用這個模型綁定:

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

[已刪除評論] – user2966445 2015-07-21 02:32:03

+0

任何downvoter可以解釋這個答案有什麼問題嗎? – 2015-10-22 17:50:16

+0

+1適用於我,儘管我只在屬性上標記了DataMember屬性,其參數名稱與屬性名稱不同。因此,我需要將GetValue方法調用和AttemptedValue引用分離出來,並對屬性進行空檢查,否則會冒NullReferenceException異常。可能不是一個壞主意不管:) – si618 2016-11-17 02:04:05

1

我花了幾個小時在一個強大的解決方案,以同樣的問題,當一個班輪將做的伎倆就好了工作:

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

HttpContext.Current.Request [「key」]將總是返回一個字符串。 – pholly 2016-08-05 20:28:01

13

您可以使用FromUri綁定屬性的Name屬性來爲方法參數使用具有不同名稱的查詢字符串參數。

如果你通過簡單的參數,而不是你的QueryParameters類型,可以綁定值是這樣的:

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

public IHttpActionResult GetValue([FromUri(Name = "cap")] string capabilities, int id)  
{ 
} 
0

我只是碰到了這一點,在我的參數類中使用一個getter返回綁定屬性。

所以在你的例子:

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

    public string Id { get; set; } 
} 

現在在你的控制器,你可以參考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物體上反射或序列化的cap屬性將被包括在內。不知道爲什麼有人需要這樣做與查詢參數。

+0

如果參數名稱是'$ cap'而不是'cap'呢? – Ali 2016-10-12 14:25:14