如果后期后,模型值的变化,表仍显示旧值期后、模型

2023-09-10 16:25:54 作者:孤凫

此行​​为使我想知道我的理智。

This behavior is making me wonder about my sanity..

我有了两个地方接受输入的一种形式,我们姑且称之为值a和valueB。用户可在任一输入值和表单提交。

I have a form that has two places that accept input, let's call them ValueA and ValueB. The user can enter a value in either one and the form submits.

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

控制器动作看起来是这样的:

The Controller Action looks like this:

public ActionResult MyControllerAction(MyViewModel viewModel)
{

//做一些其他的东西...

// do some other stuff ...

 return PartialView("MyPartialView", viewModel);
}

视图模型很简单:

The ViewModel is simply this:

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用户更改值a为5,表单提交。我可以把控制器动作断点并查看视图模型参数的两个值。在这点上,值a是5和valueB为0(由于值a的设定)。操作返回视图模型作为PartialView的一部分。早在局部的,我可以把对Html.TextBox(valueB,则,Model.ValueB,...)行设置一个断点,看到valueB,则确实是0。但是当形式呈现给浏览器,valueB,则仍然有7.价值而这是我在哪里卡住了。我甚至改变了更新的目标,以不同的分区,从而使部分刚吐出的形式某处完全不同的,但它仍然有7原值,即使我看到通过调试,该值为0回来的控制器。

Now, the unexpected piece. Say the page initially loads and ValueB has a value of 7. The user changes ValueA to 5 and the form submits. I can put a breakpoint in the controller action and see both values in the viewModel parameter. At this point, ValueA is 5 and ValueB is 0 (due to the setting of ValueA). The action returns the viewModel as part of the PartialView. Back in the partial, I can put a breakpoint on the Html.TextBox("ValueB", Model.ValueB, ...) line and see that ValueB is indeed 0. But when the form renders to the browser, ValueB still has a value of 7. And this is where I am stuck. I have even changed the Update target to a different div, so that the partial just spits out the form someplace completely different, but it still has the original value of 7, even though I saw through debugging that the value was 0 coming back from the controller.

有我丢失的东西?

推荐答案

下面是从MVC来源$ C ​​$下的文本框:

Here is the code from the MVC Source for the textbox:

     string attemptedValue = (string)htmlHelper.GetModelStateValue(name, typeof(string));
                tagBuilder.MergeAttribute("value", attemptedValue ?? ((useViewData) ? htmlHelper.EvalString(name) : valueParameter**), isExplicitValue);
                break;

而$ C $下GetModelStateValue()

And the Code for GetModelStateValue()

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

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

因此​​,所有的,如果(值> 0){值a = 0; }并不重要,因为它要使用贴值的ModelState,如果名称相匹配。

So all that if (value > 0) { ValueA = 0; } doesn't matter because its going to use the posted values in ModelState if the names match.

我已经解决这个问题的方法是吹走ModalState之前的观点呈现的,我想惹我认为模型的某些值。这是一些code我用:

The way I've fixed this is to blow away the ModalState before the view renders for certain values that I want to mess with in my view models. This is some code I've used:

    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));
        }
    }
 
精彩推荐
图片推荐