【问题标题】:ASP.Net MVC4 Razor ViewBagASP.Net MVC4 Razor ViewBag
【发布时间】:2014-03-27 03:57:11
【问题描述】:

我正在使用ViewBag 作为我的检查点,我应该在某个 div 上呈现partial view,这是我的代码:

在控制器中:

    [HttpPost]
    public ActionResult NewAppointment(appointment.AppointmentInformation model)
    {
        if (ViewBag.NextForm == null || ViewBag.NextForm == "undefined")
        {
            info.CustomerType = model.CustomerType;
            ViewBag.NextForm = "Information";
        }
        else if (ViewBag.NextForm == "Information")
        {
            info.CustomerID = String.IsNullOrEmpty(model.CustomerID) ? "" : model.CustomerID;
            info.CustomerName = String.IsNullOrEmpty(model.CustomerName) ? "" : model.CustomerName;
            info.CustomerCNum = String.IsNullOrEmpty(model.CustomerCNum) ? "" : model.CustomerCNum;
            ViewBag.NextForm = "Services";
        }
        else if (ViewBag.NextForm == "Services")
        {
            //do nothing;
        }
        return View(info);
    }

在视图中:

<form method="post">
<div id="PartialContainer">

    @if (ViewBag.NextForm == null || ViewBag.NextForm == "undefined")
    {
        @Html.Partial("CustomerType")
    }
    @if (ViewBag.NextForm == "Information")
    {
        @Html.Partial("GuestInformation")
    }
    @if (ViewBag.NextForm == "Services")
    {
        @Html.Partial("Service")
    }

</div>
<div id="ButtonArea">
    <button id="btnCancel">Cancel</button>
    <button id="btnBack">Back</button>
    <button id="btnNext">Next</button>
</div>

第三次点击btnNext,@Html.Part @Html.Partial("Service") 不起作用。但前两个@Html.Partial 工作正常..

我的代码有什么问题?

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-4 razor


    【解决方案1】:

    为什么不将步骤嵌入到表单中(在您的部分中)?

    这样,无论何时提交表单,您都会知道是哪一步,并从控制器代码中显示正确的下一步,而不是视图。

    您可以将其添加为 ViewModel 的属性,也可以直接发布它并从 Controller 中的 Request 对象中获取它。

    伪代码:

    [HttpPost]
        public ActionResult NewAppointment(appointment.AppointmentInformation model)
        {
            //get the current step or start with empty string
            //although if this is the POST method, you should have the
            //first value, set in your GET method to show the form!
            var step = Request.Params["NextForm"] ?? "";
    
            if (step == "")
            {
                info.CustomerType = model.CustomerType;
                ViewBag.NextForm = "Information";
            }
            else if (step == "Information")
            {
                info.CustomerID = String.IsNullOrEmpty(model.CustomerID) ? "" : model.CustomerID;
                info.CustomerName = String.IsNullOrEmpty(model.CustomerName) ? "" : model.CustomerName;
                info.CustomerCNum = String.IsNullOrEmpty(model.CustomerCNum) ? "" : model.CustomerCNum;
                ViewBag.NextForm = "Services";
            }
            else if (step == "Services")
            {
                //do nothing;
            }
            return View(info);
        }
    

    然后在您的视图中使用该值,以便随时将其与您的表单一起发送。

    <form method="post">
    <div id="PartialContainer">
        <input type="hidden" name="NextForm" value="@(ViewBag.NextForm ?? "")" />
    
        @if (ViewBag.NextForm == null || ViewBag.NextForm == "undefined")
        {
            @Html.Partial("CustomerType")
        }
        @if (ViewBag.NextForm == "Information")
        {
            @Html.Partial("GuestInformation")
        }
        @if (ViewBag.NextForm == "Services")
        {
            @Html.Partial("Service")
        }
    
    </div>
    <div id="ButtonArea">
        <button id="btnCancel">Cancel</button>
        <button id="btnBack">Back</button>
        <button id="btnNext">Next</button>
    </div>
    

    您每次都会通过表单获取 NextStep,然后您只需使用 ViewBag 将数据从控制器传递到视图,这是预期用途。

    希望对你有意义。

    【讨论】:

    • 这个方法对我帮助很大。
    【解决方案2】:

    HTTP is a stateless protocol。这意味着每个请求都是新的,并且客户端和服务器之间的任何先前交互大部分都被“遗忘”了。

    每次用户发出请求时,ViewBag 都会从头开始重新初始化。在我看来,您的代码假定 ViewBag 在客户端浏览器中“徘徊”,直到他们发出下一个请求。不幸的是,事情并非如此。

    ViewBag.NextForm 等于 "Services" 永远不会发生,因为应用程序不知道用户在哪里。

    在整个 HTTP 应用程序中维护状态是一个长期且持续的讨论:How can I keep "state" information between calls to my CGI program?(1996 年?)。

    我无法为您提供单一、明显的解决方案。一种方法是将表单中的信息保存为隐藏输入,然后将数据 POST 回您的控制器,以便它知道用户在哪里。您还可以在 cookiessession 中保存信息。

    【讨论】:

    • Rowan先生您好,使用session/cookies是我最后的手段,尽量不要因为机密信息而使用session/cookies。
    【解决方案3】:

    你为什么不为此使用ajax

    @using (Ajax.BeginForm("Action", "Controller", new AjaxOptions { HttpMethod = "POST",  UpdateTargetId = "PartialContainer" }))
    {
    }
    

    UpdateTargetId = "PartialContainer" 将使用部分视图更新您的 div,您必须从控制器返回部分视图

    【讨论】:

    • 其实,我是 MVC4 razor 的新手,我真的不知道如何使用 Ajax.BeginForm,但我会尝试一下。谢谢
    • @JohnPauloCastro,然后观看此视频,这将对您有所帮助youtube.com/watch?v=B59skvlroyc
    • @JohnPauloCastro,你试过视频教程吗,你添加了所需的java脚本文件吗?
    • 我目前正在下载视频,完成后我会查看。
    • @JohnPauloCastro,别忘了添加“~/Scripts/jquery.unobtrusive-ajax.min.js”文件。没有这个 ajax 将无法工作
    【解决方案4】:

    是的,确实 HTTP 是一种无状态协议

    您的值将在请求之间丢失。

    ASP.Net webforms 使用ViewState 来解决这个问题。

    ASP.Net MVC 不支持 ViewState。

    为什么不将您的数据放入 session 中?否则,您可以进行 ajax 调用 来阻止 entire page refresh

    【讨论】:

    • 由于机密数据无法使用会话,而且我不擅长处理会话,关于 ajax 调用,我尝试过,但 ViewBag.nextForm 的值保持不变。
    猜你喜欢
    • 2017-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-14
    • 2014-01-14
    • 1970-01-01
    相关资源
    最近更新 更多