首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果开机自检后Model中的值发生更改,表单仍显示旧值

如果开机自检后Model中的值发生更改,表单仍显示旧值
EN

Stack Overflow用户
提问于 2009-12-05 01:53:53
回答 4查看 5K关注 0票数 8

这种行为让我开始怀疑自己的理智..

我有一个表单,它有两个地方接受输入,我们称它们为ValueA和ValueB。用户可以在其中任何一个字段中输入值,然后表单将提交。

代码语言:javascript
复制
<div id="MyUpdateTarget">
 <% using (Ajax.BeginForm("MyControllerAction", new AjaxOptions { UpdateTargetId = "MyUpdateTarget" })) { %>
  <%=Html.TextBox("ValueA", Model.ValueA, new Dictionary<string, object> {
                                                    { "onchange", "$('#SubmitButton').click(); return false;" },
       }) %>
  <%=Html.TextBox("ValueB", Model.ValueB, new Dictionary<string, object> {
                                                    { "onchange", "$('#SubmitButton').click(); return false;" },
       }) %>
  <input id="SubmitButton" type="submit" value="Save" style="display: none;" />
 <% } %>
</div>

控制器操作如下所示:

代码语言:javascript
复制
public ActionResult MyControllerAction(MyViewModel viewModel)
{

//做一些其他的事情...

代码语言:javascript
复制
 return PartialView("MyPartialView", viewModel);
}

ViewModel就是这样的:

代码语言:javascript
复制
public class MyViewModel
{
 private int _valueA;
 private int _valueB;

 public int ValueA 
 { 
  get
  {
   return _valueA;
  }
  set
  {
   if (value > 0)
   {
    ValueB = 0;
   }
   _valueA = value;
  } 
 }
 public int ValueB 
 {
  get
  {
   return _valueB;
  }
  set
  {
   if (value > 0)
   {
    ValueA = 0;
   }
   _valueB = value;
  }
 }
}

现在,出乎意料的部分。假设页面最初加载,ValueB的值为7。用户将ValueA更改为5,然后表单提交。我可以在控制器操作中设置断点,并在viewModel参数中查看这两个值。此时,ValueA为5,ValueB为0(由于ValueA的设置)。该操作将viewModel作为PartialView的一部分返回。回到片断部分,我可以在Html.TextBox("ValueB",Model.ValueB,...)上设置一个断点。行中,可以看到ValueB确实为0。但是当表单呈现给浏览器时,ValueB的值仍然是7,这就是我遇到的问题。我甚至将Update目标更改为一个不同的div,以便partial只是在完全不同的地方显示出表单,但它仍然具有原始值7,即使我通过调试看到从控制器返回的值是0。

我是不是漏掉了什么?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-12-05 03:58:25

下面是文本框的MVC源代码中的代码:

代码语言:javascript
复制
     string attemptedValue = (string)htmlHelper.GetModelStateValue(name, typeof(string));
                tagBuilder.MergeAttribute("value", attemptedValue ?? ((useViewData) ? htmlHelper.EvalString(name) : valueParameter**), isExplicitValue);
                break;

和GetModelStateValue()的代码

代码语言:javascript
复制
    internal object GetModelStateValue(string key, Type destinationType) {
        ModelState modelState;
        if (ViewData.ModelState.TryGetValue(key, out modelState)) {
            if (modelState.Value != null) {
                return modelState.Value.ConvertTo(destinationType, null /* culture */);
            }
        }
        return null;
    }

所以发生了什么是Helper查找文本框的值,通过匹配名称,在你的ViewData.ModalState中,如果它在ModelState字典中,它完全忽略你提供的值。

所以所有的if (value > 0) { ValueA = 0;}都无关紧要,因为如果名称匹配,它将使用ModelState中的POST值。

我解决这个问题的方法是,在视图呈现某些我想在视图模型中弄乱的值之前,清除ModelState。这是我用过的一些代码:

代码语言:javascript
复制
    public static void SanitizeWildcards( Controller controller, params string[] filterStrings )
    {
        foreach( var filterString in filterStrings )
        {
            var modelState = controller.ModelState;

            ModelState modelStateValue;
            if( modelState.TryGetValue(filterString,out 
                    controller.ModelState.SetModelValue(filterString, new ValueProviderResult("","", null));
        }
    }
票数 8
EN

Stack Overflow用户

发布于 2010-11-09 21:01:10

清除整个ModelState也可以做到这一点:

代码语言:javascript
复制
ViewData.ModelState.Clear();
票数 8
EN

Stack Overflow用户

发布于 2010-07-18 22:50:54

谢谢jaf..这是vb代码:

代码语言:javascript
复制
Sub CleanForm(ByVal ParamArray Fields() As String)
    Dim modelStateValue As ModelState = Nothing
    For Each Field In Fields
        If ModelState.TryGetValue(Field, modelStateValue) Then
            ModelState.SetModelValue(Field, New ValueProviderResult(Nothing, Nothing, Nothing))
        End If
    Next
End Sub
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1848586

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档