【问题标题】:In Asp.Net MVC view dont render changes in model made by controller在 Asp.Net MVC 视图中,不呈现控制器所做的模型更改
【发布时间】:2011-11-19 02:00:42
【问题描述】:

我是 ASP.NET MVC 的新手,需要一些帮助。
当 post 触发“P01”动作时,我收到强类型模型作为参数,更改此模型实例的属性并调用“return View(model);”。
在视图中使用“@Html.TextBoxFor(m => m.p01campo01)”语法。
有人 here 遇到了类似的问题,并获得了使用我正在使用的语法的建议。
有人 here 正在使用 "" 语法。
问题是当视图呈现文本框有最后发布的值,而不是我在控制器中分配的值。

感谢所有在这里尝试帮助我的人,我将第一个有效的答案作为答案。

这是我的代码:

*************************************************
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>
}
*************************************************

【问题讨论】:

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


    【解决方案1】:

    默认情况下不会呈现帖子中的模型更改。相反,它使用模型中传递给控制器​​方法的内容。要解决此问题,请尝试添加:

    ModelState.Clear();
    

    就在 RedirectToAction 之前。

    【讨论】:

    • 谢谢,移动 ModelState.Clear();现在结束。
    【解决方案2】:

    因为它是一个 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] insted of [Acceptverb(...)]

    【讨论】:

    • 非常感谢,您的第二个答案对我有用。我也改成了[HttpPost]。我不明白第一个答案,你告诉我删除 "[AcceptVerbs(HttpVerbs.Post)]" 吗?我为获取创建了一个操作,为发布创建了另一个操作。
    • 你做对了。一个动作发布,另一个动作获取。我只是说你可以用[HttpPost] 替换[AcceptVerbs(HttpVerbs.Post)][HttpGet] 替换[Acceptverbs(HttpVerbs.Get)]。他们的想法完全相同,但这样会变得更具可读性。这只是一个细节:)
    【解决方案3】:

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

     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})          
            }
       }
    

    【讨论】:

      【解决方案4】:

      忽略下面的 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);
          }
      

      使用后重定向获取模式:

          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")) {//...}
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-13
      • 1970-01-01
      相关资源
      最近更新 更多