C# MVC 4@HTML.HiddenFor未在回发时更新

C# MVC 4@HTML.HiddenFor未在回发时更新,c#,asp.net,asp.net-mvc,asp.net-mvc-4,razor,C#,Asp.net,Asp.net Mvc,Asp.net Mvc 4,Razor,一系列页面视图的视图状态有问题——在Razor中的页面初始视图中,我使用Html.HiddenFor,如下所示: @Html.HiddenFor(x => Model.err) @Html.HiddenFor(x => Model.errField) @Html.HiddenFor(x => Model.errMessage) @Html.HiddenFor(x => Model.IsMove) 这似乎很管用。我的隐藏输入标记包含正确的值

一系列页面视图的视图状态有问题——在Razor中的页面初始视图中,我使用
Html.HiddenFor
,如下所示:

    @Html.HiddenFor(x => Model.err)
    @Html.HiddenFor(x => Model.errField)
    @Html.HiddenFor(x => Model.errMessage)
    @Html.HiddenFor(x => Model.IsMove)
这似乎很管用。我的隐藏输入标记包含正确的值。但是,当我提交表单
[HTTPPost]
并在控制器操作中用..更新模型时

       model.err = transHelper.err;
       model.errField = transHelper.errField;
       model.errMessage = transHelper.errMessage;
       return View(model);
隐藏字段似乎不会更新,它们包含初始视图中的原始值。但是,当我在同一个razor视图中的另一个上下文中使用这些字段时,就像这样

     @*      
        this seems to not update correctly...

    @Html.HiddenFor(x => Model.err)
    @Html.HiddenFor(x => Model.errField)
    @Html.HiddenFor(x => Model.errMessage)
    @Html.HiddenFor(x => Model.IsMove)

        *@
        <input type="hidden" id="err" value="@Model.err" />
        <input type="hidden" id="errField" value="@Model.errField" />
        <input type="hidden" id="errMessage" value="@Model.errMessage" />
        <input type="hidden" id="IsMove" value="@Model.IsMove" />

    </div>
以下是我的看法:

        @model App.Models.HomePageModel
    @{
        ViewBag.Title = "Product Categorizer";
    }
    <form id="formData" method="post" action="/Home/Index">
        @Html.AntiForgeryToken()
        <fieldset>
            <div>

            @Html.HiddenFor(model => model.err)
            @Html.HiddenFor(model => model.errField)
            @Html.HiddenFor(model => model.errMessage)
            @Html.HiddenFor(model => model.IsMove)

            <input type="hidden" id="myerr" value="@Model.err" />
            <input type="hidden" id="myerrField" value="@Model.errField" />

            </div>

           <div class="section group">
                <div class="col span_2_of_2">
                     <div class="message" id ="message">
                         @if (Model.err < 0)
                         {
                             <span style="color: purple;">@Model.errMessage (@Model.err) - (@Model.errField)</span>
                         }
                         else if (Model.err > 0)
                         {
                             <span style="color:red;">@Model.errMessage (@Model.err) (@Model.errField)</span>
                         } else {
                            <span>@Model.errMessage (@Model.err) (@Model.errField)</span>
                         }
                         </div>
                     </div>
            </div>

            <div class="section group" id="workspace">
                  @Html.Partial("_WorkspacePartial", Model)
            </div>
              <div class="section group" id="details">
                  @Html.Partial("_DetailPartial", Model)
              </div>


        </fieldset>
        </form>
@model App.Models.HomePageModel
@{
ViewBag.Title=“产品分类程序”;
}
@Html.AntiForgeryToken()
@Html.HiddenFor(model=>model.err)
@Html.HiddenFor(model=>model.errField)
@Html.HiddenFor(model=>model.errMessage)
@Html.HiddenFor(model=>model.IsMove)
@如果(Model.err<0)
{
@Model.errMessage(@Model.err)-(@Model.errField)
}
否则如果(Model.err>0)
{
@Model.errMessage(@Model.err)(@Model.errField)
}否则{
@Model.errMessage(@Model.err)(@Model.errField)
}
@Html.Partial(“_workspaceportial”,Model)
@Html.Partial(“\u DetailPartial”,Model)
这是我的模型:

 public class HomePageModel
 {
    public int FromStore { get; set; }

    //  the "To" part of the copy/move transaction
    public int ToStore { get; set; }

    // a list of the copy/move transaction
    public List<int> Details { get; set; }


    // true is move false is copy
    public bool IsMove { get; set; }

    // current message
    public int err { get; set; }
    public int errField { get; set; }
    public string errMessage { get; set; }
公共类主页模型
{
来自存储区的公共int{get;set;}
//复制/移动事务的“到”部分
公共int-ToStore{get;set;}
//复制/移动事务的列表
公共列表详细信息{get;set;}
//真是移动假是复制
公共bool IsMove{get;set;}
//当前消息
公共int err{get;set;}
public int errField{get;set;}
公共字符串errMessage{get;set;}

我认为您应该这样使用它们:

@Html.HiddenFor(x => x.Err)
@Html.HiddenFor(x => x.ErrField)
@Html.HiddenFor(x => x.ErrMessage)
@Html.HiddenFor(x => x.IsMove)
没有看到您的模型,我假设它看起来像这样:

public class ErroViewModel
{
  public string Err { get; set; }
  public string ErrField { get; set; }
  public string ErrMessage { get; set; }
  public bool IsMove { get; set; }
}
如果没有,则应与上述公共财产类似

更新

在您的get中,您有以下内容吗

public ActionResult Index(HomePageModel model)
{
   var model = new HomePageModel();
   return View(model);
}
我还将更改您的表格:

 <form id="formData" method="post" action="/Home/Index">

默认的HtmlHelpers行为(@Html.HiddenFor等)的行为与您描述的完全相同

i、 e.您在帖子上对ViewModel所做的任何更改都会被执行,从帖子返回的任何更改都会被视图接收,但在使用HTMLHELPERS重新呈现时,先前的帖子值优先于更改的ViewModel值


要以快速且肮脏的方式“修复”此行为,请在从HttpPost ActionMethod返回之前清除ModelState.clear()。

正如Joedotn所述,这不是预期的行为。另一个“快速修复”是为隐藏字段编写html代码,并仅更新模型中的值,例如:



使用与模型属性相同的
id
name
,更新后的值将在回发后呈现。

我最近遇到了类似的问题,并最终编写了新的simple helper方法+2重载。我在这里分享它,以防任何人仍在寻找解决此“功能”的方法有时很烦人

public static class CustomExtensions
{
    public static MvcHtmlString HiddenFor2<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
    {
        ReplacePropertyState(htmlHelper, expression);
        return htmlHelper.HiddenFor(expression);
    }

    public static MvcHtmlString HiddenFor2<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes)
    {
        ReplacePropertyState(htmlHelper, expression);
        return htmlHelper.HiddenFor(expression, htmlAttributes);
    }

    public static MvcHtmlString HiddenFor2<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes)
    {
        ReplacePropertyState(htmlHelper, expression);
        return htmlHelper.HiddenFor(expression, htmlAttributes);
    }

    private static void ReplacePropertyState<TModel, TProperty>(HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
    {
        string text = ExpressionHelper.GetExpressionText(expression);
        string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(text);
        ModelStateDictionary modelState = htmlHelper.ViewContext.ViewData.ModelState;

        if (modelState.ContainsKey(fullName))
        {
            ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
            ValueProviderResult currentValue = modelState[fullName].Value;
            modelState[fullName].Value = new ValueProviderResult(metadata.Model, Convert.ToString(metadata.Model), currentValue.Culture);
        }
    }
}

值得一提的是,它也适用于集合。

您的视图模型中需要一个键。如果您的视图模型中没有任何名为Id的属性,请使用[key]将其中一个属性(预期为uniqe identifiyer)设置为key

[Key]
Myproperty {get;set;}

我有一个类似的问题,就这样解决了

@Html.TextBoxFor(m => m.Email, new { onclick = "this.select()", Value = Model.Email, Placeholder = "E-Mail" })
你可以试试

<input type="hidden" id="SomeFieldID" name="SomeFieldID" value="@Model.SomeFieldID" />


我的模型使用公共属性。在表达式方面,我尝试了所有方法,包括你的建议,但似乎没有任何影响。是的,在我的get中,我创建了HomePageModel的一个实例。至于表单。我正在使用jquery进行一些表单操作,所以我将其编码为那样。嗯,不确定会出现什么问题因为这一切对我来说都很好。仍然是一个问题吗?是
ModelState
导致了它。请参阅其他答案。为什么不使用
[HttpPost]
attribute?这非常脏,因为所有的验证消息都被清除了,所以请注意!我以为我疯了。我不明白。模型的任何属性上都没有必需的属性。为什么返回视图会使一个属性的HiddenFor为空?在执行ModelState之后。清除我得到的是value好的!!!为什么在从HttpPost ActionMethod返回之前清除ModelState.clear()?奇怪的行为(仍然存在于Razor页面中)。这似乎是因为默认情况下,
验证系统将不可为null的参数或属性视为具有[Required]属性。
根据文档(),但即使是用作隐藏输入的单个
string
type(nullable)模型属性(通过
asp for
)也会受到此行为的影响,其值会自动恢复为以前的值。这很有魅力,谢谢!这看起来好像已经在两年前发布了
[Key]
Myproperty {get;set;}
@Html.TextBoxFor(m => m.Email, new { onclick = "this.select()", Value = Model.Email, Placeholder = "E-Mail" })
<input type="hidden" id="SomeFieldID" name="SomeFieldID" value="@Model.SomeFieldID" />