2013-03-22 121 views
3

需要幫助創建MVC自定義模型綁定器以將多個模型元組發佈到控制器。從未使用自定義模型聯編程序。已經看過這個問題的其他答案,但似乎並沒有接近處理模型的元組或提供所需的解決方案。任何想法都表示讚賞。 - 感謝爲模型元組創建MVC自定義模型綁定器

查看

@model Tuple<Contact, Communications, Addresses> 
@using (Html.BeginForm()) { 
    <div id="contact"> 
    <div class="editor-label"> 
     @Html.LabelFor(m => m.Item1.FirstName) 
    </div> 
    <div class="editor-field"> 
     @Html.TextBoxFor(m => m.Item1.FirstName) 
    </div> 
    <div class="editor-label"> 
     @Html.LabelFor(m => m.Item1.LastName) 
    </div> 
    <div class="editor-field"> 
     @Html.TextBoxFor(m => m.Item1.LastName) 
    </div> 
    <div> 
     <input type="submit" value="Create" /> 
    </div> 
    </div> 
    <div id="communication"> 
    <div class="editor-label"> 
     @Html.LabelFor(m => m.Item2.TelephoneValue) 
    </div> 
    <div class="editor-field"> 
     @Html.TextBoxFor(m => m.Item2.TelephoneValue) 
    </div> 
    </div> 
    <div id="address"> 
    <div class="editor-label"> 
     @Html.LabelFor(m => m.Item3.Address1) 
    </div> 
    <div class="editor-field"> 
     @Html.TextBoxFor(m => m.Item3.Address1 
    </div> 
    <div class="editor-label"> 
     @Html.LabelFor(m => m.Item3.City) 
    </div> 
    <div class="editor-field"> 
     @Html.TextBoxFor(m => m.Item3.City) 
    </div> 
    <div class="editor-label"> 
     @Html.LabelFor(m => m.Item3.StateProvince) 
    </div> 
    <div class="editor-field"> 
     @Html.TextBoxFor(m => m.Item3.StateProvince) 
    </div> 
    <div class="editor-label"> 
     @Html.LabelFor(m => m.Item3.PostalCode) 
    </div> 
    <div class="editor-field"> 
     @Html.TextBoxFor(m => m.Item3.PostalCode, new { id = "zip", style = "width:90px;" }) 
    </div> 
    </div> 
} 

位指示

[HttpPost] 
public ActionResult CreateContact(Tuple<Contact, Communications, Addresses> tuple) { 
     //…. Do tuple processing to transfer values to add values to App Service here. 
} 

回答

0

對於那些可能對此方法的實施結果感興趣的人,我想報告它已經很好地完成了,並且超出了所有的靈活性期望。最初,它被用來解決三個模型對象元組,它已經成功擴展到四個模型對象元組,但請記住,這種方法的限制有8個項目,但是有一種方法可以將元組級聯到更多物品,不知道它是否實用。下面是一些代碼片段,可能是有用的:

//Custom Model Binder 
public class TupleModelBinder : DefaultModelBinder 
{ 
    protected override object CreateModel(ControllerContext controllerContext, 
       ModelBindingContext bindingContext, Type modelType) 
    { 
     if (modelType == typeof(Tuple<ContactModel, CommunicationModel, AddressModel>)) 
      return new Tuple<ContactModel, CommunicationModel, AddressModel>(new ContactModel(), new CommunicationModel(), new AddressModel()); 
     if (modelType == typeof(Tuple<ContactModel, CommunicationModel, AddressModel, CustomerModel>)) 
      return new Tuple<ContactModel, CommunicationModel, AddressModel, CustomerModel>(new ContactModel(), new CommunicationModel(), new AddressModel(), new CustomerModel()); 

     return base.CreateModel(controllerContext, bindingContext, modelType); 
     } 
} 

// In Global.asax Application_Start() 
    ModelBinders.Binders.DefaultBinder = new TupleModelBinder(); 
1

你爲什麼不嘗試保持一個新的模式裏面的「聯繫人,通訊,地址」模型,並將其綁定到視圖。

它會使處理非常簡單。

0

的方便使用一個元組,就好像它是需要綁定行添加到每個元組定製綁定模型會大大減少的。

這是一個自定義模型聯編程序,它將與所有元組一起工作。它會遞歸調用它自己,以便註冊的類型綁定器仍然可以運行。現在只需要在一個地方改變你的元組模型,這是理想的。

public class CustomModelBinder : DefaultModelBinder 
{ 
    private static Type _tupleInterfaceType = Type.GetType("System.ITuple", true, false); 

    protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) 
    { 
     if (modelType.FindInterfaces((a, b) => a == (Type)b, _tupleInterfaceType).Length == 1) 
     { 
      object[] args = new object[modelType.GenericTypeArguments.Length]; 
      for (int i = 0; i < args.Length; i++) 
      { 
       if (modelType.GenericTypeArguments[i].IsValueType) args[i] = Activator.CreateInstance(modelType.GenericTypeArguments[i]); 
       else args[i] = CreateModel(controllerContext, bindingContext, modelType.GenericTypeArguments[i]); 
      } 
      return Activator.CreateInstance(modelType, args); 
     } 
     return base.CreateModel(controllerContext, bindingContext, modelType); 
    } 
} 

注:必須從字符串創建System.ITuple接口類型,因爲它是一個受保護的接口。

我希望這可以節省您一些時間。 8)