编写剃刀表单的正确方法是什么,以便模型正确绑定到表单POST?

时间:2015-11-17 23:26:23

标签: c# asp.net-mvc razor

我有时会发现自己正在为以下形式编写剃刀:

<h2>Subscription form for @Model.UserName</h2>
@using (Html.BeginForm("Subscribe", "Subscribe", FormMethod.Post)
{
   @Html.Partial("CreditCardForm", Model.PaymentInfo)
   @Html.LabelFor(m => m.PaymentInfo.PromoCode)
   @Html.EditorFor(m => m.PaymentInfo.PromoCode, new{Name="PromoCode"})

   <button type=submit>Submit</button>
}

CreditCardForm partial在不同的视图中重复使用(即更新信用卡详细信息),在这种情况下,不需要PromoCode,因此以这种方式将其拉出。这可能如下所示:

<h2>Update Credit Card form for @Model.UserName</h2>
@using (Html.BeginForm("UpdateCreditCard", "Subscribe", FormMethod.Post)
{
   @Html.Partial("CreditCardForm", Model.PaymentInfo)

   <button type=submit>Submit</button>
}

这里要注意的另一件事是这些视图中使用的模型有两个属性:UserName和PaymentInfo; UserName是仅显示属性,PaymentInfo是要回发的模型。

请注意底部PromoCode属性的name属性的覆盖,以便PromoCode值正确绑定到回发到控制器操作的模型。保持原样意味着PromoCode编辑器的默认名称为PaymentInfo.PromoCode,它不能正确绑定到模型。

表单发布的操作方法如下所示:

    [HttpPost]
    public ActionResult Subscribe(PaymentInfo paymentInfo)
    {
        ...
    }

这对我来说总是感觉像是一个黑客 - 有没有更好/正确的方法来做到这一点?

2 个答案:

答案 0 :(得分:1)

您可以将Promocode保留在您的PaymentInfo模型之外。根据MVC更加标准。

public class SubscribeModel
{
   public string UserName {get;set;}
   public string PromoCode {get;set;}
   public PaymentInfo PaymentInfo {get;set;}
}

public class UpdateCreditCardModel
{
   public PaymentInfo PaymentInfo {get;set;}
}

public class PaymentInfo
{
   //Payment Info Properties goes here.
}

订阅者视图

<h2>Subscription form for @Model.UserName</h2>
@using (Html.BeginForm("Subscribe", "Subscribe", FormMethod.Post)
{
   @Html.Partial("CreditCardForm", Model.PaymentInfo)
   @Html.LabelFor(m => m.PromoCode)
   @Html.EditorFor(m => m.PromoCode)

   <button type=submit>Submit</button>
}

在您的控制器中

    [HttpPost]
    public ActionResult Subscribe(SubscribeModel model)
    {
       //Access model.Promocode and model.PaymentInfo here.
    }

    [HttpPost]
    public ActionResult UpdateCreditCard(UpdateCreditCardModel model)
    {
       //Access model.PaymentInfo here.
    }

答案 1 :(得分:1)

是的,这是一个黑客攻击。您正在完全反对该框架,该框架提供了完全按照您要执行的操作的机制。他们称之为EditorTemplates。

Partials和EditorTemplates类似,但只有EditorTemplates创建正确的表单名称以自动支持模型绑定。部分不会,至少不是你使用它们的方式。

将您的部分转换为EditorTemplate,然后在后期操作中接受您的父模型。