2014-04-10 41 views
2

我有一個動作:MVC模式類型的條件結合

[HttpPost] 
public ActionResult(Animal a) 
{ 

} 

我想a成爲RabbitDog根據輸入表格數據。有沒有簡單的方法來實現這一點?
謝謝

+0

http://stackoverflow.com/questions/9417888/mvc-3-model-binding-a-sub-type-abstract-class-or-interface –

回答

2

爲了得到這個工作,你正在尋找建立您的行動接受一個動態參數,一個ModelBinder將轉換爲相應的類型,是一個RabbitDog

[HttpPost] 
public ActionResult([ModelBinder(typeof(AnimalBinder))] dynamic a) 
{ 

} 

由於Action不知道對象是什麼,它需要一種知道該對象轉換的方法。你需要兩件事才能做到這一點。首先,你必須在你的瀏覽嵌入,EditorTemplate,什麼,什麼,你有約束力的模式是:

@Html.Hidden("ModelType", Model.GetType()) 

二,型號粘結劑,將創建相應類型的對象的基礎上,ModelType場上面指定:

public class AnimalBinder : DefaultModelBinder 
    { 
     protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) 
     { 
      var typeValue = bindingContext.ValueProvider.GetValue("ModelType"); 
      var type = Type.GetType((string)typeValue.ConvertTo(typeof(string)), true); 
      if (!typeof(Animal).IsAssignableFrom(type)) 
      { 
       throw new InvalidOperationException("Bad Type"); 
      } 
      var model = Activator.CreateInstance(type); 
      bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, type); 
      return model; 
     } 
    } 

一旦全部到位,如果你檢查傳遞到Action動態a對象,你會看到它是Rabbit型或Dog的依據是什麼頁面模型是。

+0

感謝您的詳細解答!是的,這將適用於簡單的情況。請你能解釋一下像下面這樣更復雜的事情嗎?如果我有數組,甚至嵌套對象通過瀏覽器發送到服務器?有沒有辦法讓聯編程序「知道」如何將每個單獨的客戶端對象轉換爲模型類型,但不解釋如何使用數組或嵌套對象?在我的例子中,我有一組「動物」(表單上的動物[0],動物[1]等),並且它們中的每一個也可以具有嵌套對象類型,這些對象也應該在活頁夾中正確「解析」。 – LINQ2Vodka

+0

這是一個API?如果是這樣,您可能將這種複雜的邏輯分解爲多個API操作或資源,因此您無需過多依賴模型綁定器。 – NWard

+0

@ LINQ2Vodka - 請記住,當你發佈數據時,它只是HTML表單字段......沒有什麼特別的。沒有魔法。有些東西必須能夠告訴模型聯編程序它是什麼類型的對象,並且Http沒有提供足夠的信息來執行此操作,因此您必須將這些信息構建到發佈的數據中。 –