2011-12-14 87 views
9

好的模型,可以說我有像這樣一個URL,它通過HTTP動詞GET映射到控制器的動作我有如下:如何綁定URL參數屬性名稱不同

GET /foo/bar?sort=asc&r=true 

我怎樣才能結合這對我對我的控制器操作模式Bar我有如下:

class Bar { 
    string SortOrder { get; set; } 
    bool Random { get; set; } 
} 

public ActionResult FooBar(Bar bar) { 
    // Do something with bar 
    return null; 
} 

注意,屬性名不會也未必匹配URL參數的名稱。另外,這些是可選的url參數。

+1

我只是添加一個類與匹配的屬性名稱,但我很感興趣,看看你是否可以配置模型聯編程序綁定到任意的屬性名稱。也許有一些屬性使用... – dotjoe 2011-12-14 16:18:11

+1

我無法得到它,爲什麼屬性無法匹配的URL參數? – gdoron 2011-12-14 16:29:34

回答

7

模型聯編程序將它從視圖中獲取的參數與名稱中的動作相匹配,因此如果它們不匹配,綁定將不起作用。

選項你有:

  1. 匹配輸入名稱的模型屬性的名稱...但你說你不能這樣做,(對於一些未知的原因)。
  2. 編寫自定義模型活頁夾。 *
  3. 使用具有前綴的Bind屬性 - 儘管它仍會強制您輸入名稱接近模型屬性名稱。

所以基本上,你不能做到你想要的。


更新:

您的評論的性能可以匹配參數名寫的,所以不是寫自定義屬性,也許會成功做了綁定,只寫一個視圖模型(該VM fromMVC ...)調整url參數名稱。

編寫自定義的模型綁定不建議用MVC團隊:

一般情況下,我們建議人們不要寫自定義模型粘合劑,因爲他們難以得到的權利和他們很少需要
here

9

它不支持開箱即用,但你可以這樣做:

class BarQuery : Bar { 

    public string sort { get { return SortOrder; } set { SortOrder = value; } } 
    public bool r { get { return Random; } set { Random = value; } } 
} 

public ActionResult FooBar(BarQuery bar) { 
    // Do something with bar 
} 

您可以實現自定義IModelBinder,但手動映射更容易。


如果你可以改變的酒吧類,你可以使用這個屬性:

class FromQueryAttribute : CustomModelBinderAttribute, IModelBinder { 

    public string Name { get; set; } 

    public FromQueryAttribute() { } 

    public FromQueryAttribute(string name) { 
     this.Name = name; 
    } 

    public override IModelBinder GetModelBinder() { 
     return this; 
    } 

    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { 
     return controllerContext.HttpContext.QueryString[this.Name ?? bindingContext.ModelName]; 
    } 
} 

class Bar { 

    [FromQuery("sort")] 
    string SortOrder { get; set; } 

    [FromQuery("r")] 
    bool Random { get; set; } 
} 

public ActionResult FooBar(Bar bar) { 
    // Do something with bar 
    return null; 
} 
1

您可以實現IModelBinder到您的傳入參數映射到您選擇的對象所提供的名稱定義傳入的參數。否則,你將不得不依靠參數順序和/或類型來推斷正確的綁定,這似乎是一個非常糟糕的選擇。

3

我很久以前有同樣的問題,並使用安德拉什佐爾坦這個棧解決方案:對物業Asp.Net MVC 2 - Bind a model's property to a different named value

我設置ModelBinder的屬性上我的課和BindAlias:

[ModelBinder(typeof(DefaultModelBinderEx))] 
    public class MyModel 
    { 
     [Required] 
     [BindAlias("new")] 
     public int? Amount { get; set; } 

如果你不能改變或不能訪問你的模型文件來設置屬性,你仍然可以創建一個自定義模型綁定器,或者製作一個特定的對象,而不是你將映射到你的模型(AutoMapper是有用的)

1

There沒有免費的MVC.Net Mo刪除綁定功能,可以給你開箱即用的功能。當我需要做這樣的事情時,它真的讓我思考我的建模,這幾乎總是讓我爲我的視圖綁定創建一個ViewModel,爲我的存儲庫存儲創建一個EntityModel。

我喜歡使用AutoMapper在這些不同類型之間進行轉換。使用AutoMapper的最好的部分是,它可以讓你不必爲控制器中的每個Action而反覆編寫映射邏輯。只需在初始化部分使用AutoMapper設置一次,並在將來執行此類操作即可。

Mapper.Map<Bar>(barViewModel); 
相關問題