此行为使我想知道我的理智。
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));
}
}