В представлении Asp.Net MVC не отображать изменения в модели, сделанные контроллером

Я новичок в ASP.NET MVC и нуждаюсь в некоторой помощи.
Когда действие «P01» запускается по почте, я получаю строго типизированную модель в качестве параметра, меняю свойства этого экземпляра модели и вызываю «return View (model);».
Я вижу, что я использую синтаксис "@ Html.TextBoxFor (m => m.p01campo01)".
Кто-то здесь была аналогичная проблема, и вы получили совет по использованию синтаксиса im using.
Кто-то здесь использует синтаксис "‹% = 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>
}
*************************************************

person newway    schedule 19.11.2011    source источник


Ответы (4)


Поскольку это HttpPost HTML-помощники сначала обращаются к данным POSTed, а только потом к модели.

Вы должны удалить свойство из состояния:

[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(...)]

person Joao    schedule 19.11.2011
comment
Большое спасибо, ваш второй ответ мне подходит. Я тоже перешел на [HttpPost]. Я не понимаю первый ответ, вы сказали мне удалить [AcceptVerbs (HttpVerbs.Post)]? Я создал одно действие для получения и другое для публикации. - person newway; 19.11.2011
comment
Ты делаешь это правильно. Одно действие - Опубликовать, другое - Получить. Я только что сказал, что вы можете заменить [AcceptVerbs(HttpVerbs.Post)] на [HttpPost] и [Acceptverbs(HttpVerbs.Get)] на [HttpGet]. Они точно так же думают, но так они становятся более читаемыми. Это просто мелочь :) - person Joao; 20.11.2011

Изменения модели, внесенные в сообщение, по умолчанию не отображаются. Вместо этого он использует то, что было передано в модели методу контроллера. Чтобы исправить это, попробуйте добавить:

ModelState.Clear();

непосредственно перед RedirectToAction.

person Jeff Siver    schedule 19.11.2011
comment
Спасибо, перемещение ModelState.Clear (); заканчивать сейчас. - person newway; 19.11.2011

это очень уродливый обходной путь, который вы можете попробовать

 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})          
        }
   }
person Rafay    schedule 19.11.2011

Игнорируйте предложение 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")) {//...}
person Pencho Ilchev    schedule 19.11.2011
comment
Я новичок в MVC и никогда не слышал о PRG, я нашел ссылку об этом здесь: stevefenton.co.uk/Content/Blog/Date/201104/Blog/ и здесь: stevefenton.co.uk/Content/Blog/Date/201007/Blog/ - person newway; 19.11.2011
comment
Я нашел здесь: blog.jorritsalverda.nl / 2010/03/10 / тоже PRG нужен? - person newway; 19.11.2011