在Asp.Net MVC视图中,控制器对模型所做的更改不会渲染到视图中。

5

我是ASP.NET MVC的新手,需要一些帮助。
当通过post方法触发“P01”操作时,我会将强类型模型作为参数接收到,并更改该模型实例的属性,然后调用“return View(model);”。
在视图中,我使用“@Html.TextBoxFor(m => m.p01campo01)”语法。
有人在这里遇到了类似的问题,并获得了使用我正在使用的语法的建议。
有人在这里使用“<%= Html.TextBox(“Person.LastName”,ViewData.Model.LastName)%>”语法。
问题在于当视图被呈现时,文本框具有上次发布的值,而不是我在控制器中分配的值。

感谢每个试图帮助我的人,我将第一个起作用的答案作为答案。

这是我的代码:

*************************************************
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;

namespace MyTest.Models
{
    //-------
    public class testePg01
    {        
        [DataType(DataType.Text)]
        [Display(Name = "p01campo01")]
        public string p01campo01 { get; set; }

        [DataType(DataType.Text)]
        [Display(Name = "p01campo02")]
        public string p01campo02 { get; set; }

    }
    //-------
}
*************************************************

*************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MyTest.Models;

namespace MyTest.Controllers
{
    public class TesteController : Controller
    {
        //-------
        [AcceptVerbs(HttpVerbs.Get)]        
        public ActionResult P01()
        {
            return View();
        }
        //-------
        [AcceptVerbs(HttpVerbs.Post)]
        [ValidateAntiForgeryToken]
        public ActionResult P01(testePg01 model)
        {
            model.p01campo01 = model.p01campo01 + "#updatedHereButNotInView";
            model.p01campo02 = model.p01campo02 + "#updatedHereButNotInView";
            return View(model); // it dont return updated
        }
        //-------

    }
}
*************************************************

*************************************************
@model MyTest.Models.testePg01

@{
    ViewBag.Title = "P01";
}

<h2>P01</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@Html.ValidationSummary(true, "Erro na pagina.")

@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    <div>    
        <fieldset>
            <legend>Test P01</legend>

            <div class="editor-label">
                @Html.LabelFor(m => m.p01campo01)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(m => m.p01campo01)
                @Html.ValidationMessageFor(m => m.p01campo01)
            </div>

            <div class="editor-label">
                @Html.LabelFor(m => m.p01campo02)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(m => m.p01campo02)
                @Html.ValidationMessageFor(m => m.p01campo02)
            </div>
            <p>
                <input type="submit" value="P01" />
            </p>
        </fieldset>
    </div>
}
*************************************************
4个回答

7

默认情况下,发布后所做的模型更改不会被渲染。相反,它使用传递给控制器方法的模型内容。要解决此问题,请尝试添加以下内容:

ModelState.Clear();

在 RedirectToAction 之前立即执行。


谢谢,现在将ModelState.Clear();移动到最后。 - newway

6
因为它是HttpPost HTML助手,所以首先查找POST数据,仅在此之后才查找模型。
您必须从状态中删除该属性:
[AcceptVerbs(HttpVerbs.Post)]
[ValidateAntiForgeryToken]
public ActionResult P01(testePg01 model)
{
    ModelState.Remove("p01campo01");
    ModelState.Remove("p01campo02");

    model.p01campo01 = model.p01campo01 + "#updatedHereButNotInView";
    model.p01campo02 = model.p01campo02 + "#updatedHereButNotInView";

    return View(model);         
}

由于ModelState是一个字典,您还可以使用Clear()来从状态中删除所有属性:

ModelState.Clear();

顺便提一下,在MVC3中,您可以使用[HttpPost][HttpGet]代替[Acceptverb(...)]


非常感谢,你的第二个答案对我有用。我也改成了 [HttpPost]。我不理解第一个答案,你是让我删除 "[AcceptVerbs(HttpVerbs.Post)]" 吗?我为获取和发布创建了两个操作。 - newway
你做得很好。一个动作用于发布,另一个用于获取。我只是想说,你可以用[HttpPost]替换[AcceptVerbs(HttpVerbs.Post)],用[HttpGet]替换[Acceptverbs(HttpVerbs.Get)]。它们完全相同,但这样更易读。这只是一个细节 :) - Joao

0

这是一种非常丑陋的解决方法,您可以尝试一下

 public class TesteController : Controller
    {
        //-------
        [AcceptVerbs(HttpVerbs.Get)]        
        public ActionResult P01(string val1,string val2)
        {
            var model = new testePg01();
            if(!(String.IsEmptyOrNull(val1)&&String.IsEmptyOrNull(val2)))
                  { 
                       model.p01campo01  = val1;
                       model.p01campo02 = val2;

                  }
            return View(model);
        }
        //-------
        [AcceptVerbs(HttpVerbs.Post)]
        [ValidateAntiForgeryToken]
        public ActionResult P01(testePg01 model)
        {
            model.p01campo01 = model.p01campo01 + "#updatedHereButNotInView";
            model.p01campo02 = model.p01campo02 + "#updatedHereButNotInView";
            return RedirectToAction("P01",{val1=model.p01campo01,val2=model.p01campo02})          
        }
   }

0

忽略下面的PRG建议。它很丑陋。相反,请使用:

public ActionResult P01(TestePg01 model)
    {
        model.P01campo01 = model.P01campo01 + "#updatedHereButNotInView";
        model.P01campo02 = model.P01campo02 + "#updatedHereButNotInView";
        ModelState.Clear(); //this will re-populate the view

        return View(model);
    }

使用Post-Redirect-Get模式:

    public class TesteController : Controller
{
    //-------
    [AcceptVerbs(HttpVerbs.Get)]
    public ViewResult P01(TestePg01 o)
    {
        return base.View(o);
    }
    //-------
    [AcceptVerbs(HttpVerbs.Post)]
    [ValidateAntiForgeryToken]
    public ActionResult P01Post(TestePg01 model)
    {
        model.P01campo01 = model.P01campo01 + "#updatedHereButNotInView";
        model.P01campo02 = model.P01campo02 + "#updatedHereButNotInView";
        return RedirectToAction("P01", model);
    }
    //-------
}

在视图中:

@using (Html.BeginForm("P01Post", "Teste")) {//...}

我对MVC不熟悉,以前也没听说过PRG,我在这里找到了相关链接:http://www.stevefenton.co.uk/Content/Blog/Date/201104/Blog/ASP-NET-MVC-Post-Redirect-Get-Pattern/ 和 http://www.stevefenton.co.uk/Content/Blog/Date/201007/Blog/Avoid-MVC-Anti-Patterns/。 - newway
我在这里找到了:http://blog.jorritsalverda.nl/2010/03/10/maintainable-mvc-post-redirect-get-pattern/,PRG是必要的吗? - newway

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接