ASP.NET MVC:使用多个viewModels以及如何将数据正确传递给模型?

时间:2016-09-28 07:25:48

标签: c# asp.net asp.net-mvc razor model-view-controller

基于我上一篇question以及我得到的答案,我正在思考它们以及我的应用程序的真正问题是什么。而且我想你们帮助我把你们所写的所有内容弄清楚了,真的很感激。所以我做了一个小但有效的例子来证明我的问题:

我的模特:

public class Order
    {
        public int OrderID { get; set; }
        public string NameOfCustomer { get; set; }
        public string Address { get; set; }
    }

包含我需要的另外两个ViewModel的ViewModel:

public class ViewModelOrder
    {
        public ViewModelSendItNow viewModelSenditNow { get; set; }
        public ViewModelSafeForLater viewModelSafeForLater { get; set; }
    }

ViewModel SendItNow:

public class ViewModelSendItNow
    {
        [Required]
        public string NameOfCustomer { get; set; }
        [Required]
        public string Address { get; set; }
    }

ViewModel SafeForLater:

public class ViewModelSafeForLater
    {
        public string NameOfCustomer { get; set; }
        public string Address { get; set; }
    }

观点:

@model ProblemExample.Models.ViewModelOrder

@{
    ViewBag.Title = "CreateOrder";
}

<h2>CreateOrder</h2>

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })

        @if (Request.Form["SafeForLater"] != null)
        {
            @Html.TextBoxFor(m => m.viewModelSafeForLater.NameOfCustomer)
            @Html.TextBoxFor(m => m.viewModelSafeForLater.Address)
        }

        else
        {
            @Html.TextBoxFor(m => m.viewModelSenditNow.NameOfCustomer)
            @Html.TextBoxFor(m => m.viewModelSenditNow.Address)
        }
        <hr />
        <button class="formular-button-submit" type="submit" name="SenditNow">Send it now!</button>
        <button class="formular-button-submit" type="submit" name="SafeForLater">Safe it for later!</button>
    </div>
}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

控制器:

public ActionResult CreateOrder()
        {
            ViewModelOrder viewModel = new ViewModelOrder();
            return View(viewModel);
        }

        [HttpPost]
        public ActionResult CreateOrder(ViewModelOrder viewModel)
        {
            if (Request.Form["SafeForLater"] != null)
            {
                Order myOrder = new Order()
                {
                    NameOfCustomer = viewModel.viewModelSafeForLater.NameOfCustomer,
                    Address = viewModel.viewModelSafeForLater.Address
                };
                db.Orders.Add(myOrder);
                db.SaveChanges();
            }

            else
            {
                Order myOrder = new Order()
                {
                    NameOfCustomer = viewModel.viewModelSenditNow.NameOfCustomer,
                    Address = viewModel.viewModelSenditNow.Address
                };
                db.Orders.Add(myOrder);
                db.SaveChanges();
            }
            return View(viewModel);
        }

因此,用户应该看到一个表单,当他决定立即发送表单时,验证应该跳入,如果他想保存它以供日后使用,则不应该进行验证。这就是为什么我尝试用视图中的2个按钮来做到这一点。问题是,该示例适用于现在发送它,它会像应该的那样保存在数据库中,但是当我点击“安全”按钮时,我会得到一个Nullreference异常,我真的不知道为什么。所以也许你们看到我的代码中的错误,并给我一个提示,我可以解决这个问题或者我可以尝试的方法。

此致

1 个答案:

答案 0 :(得分:0)

答案很简单,因为你在页面加载时只渲染了2个文本框,所以只有两个文本框会一次呈现,这是现在发送它,因为Request.Form["SafeForLater"]似乎是空的,所以,代码移动到else块并仅呈现现在发送文本框。

你应该渲染两者并且只能使用css隐藏/显示它们。 所以你的代码应该是这样的:

@model ProblemExample.Models.ViewModelOrder

@{
    ViewBag.Title = "CreateOrder";
}

<h2>CreateOrder</h2>

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })

        @if (Request.Form["SafeForLater"] != null)
        {
            @Html.TextBoxFor(m => m.viewModelSafeForLater.NameOfCustomer)
            @Html.TextBoxFor(m => m.viewModelSafeForLater.Address)
            <div style="display:none">
               @Html.TextBoxFor(m => m.viewModelSenditNow.NameOfCustomer)
               @Html.TextBoxFor(m => m.viewModelSenditNow.Address)
            </div>
        }

        else
        {
            <div style="display:none">
               @Html.TextBoxFor(m => m.viewModelSafeForLater.NameOfCustomer)
               @Html.TextBoxFor(m => m.viewModelSafeForLater.Address)
            </div>

            @Html.TextBoxFor(m => m.viewModelSenditNow.NameOfCustomer)
            @Html.TextBoxFor(m => m.viewModelSenditNow.Address)
        }
        <hr />
        <button class="formular-button-submit" type="submit" name="SenditNow">Send it now!</button>
        <button class="formular-button-submit" type="submit" name="SafeForLater">Safe it for later!</button>
    </div>
}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}