MVC crazy property lose its value. Does Html.HiddenFor bug?

一个人想着一个人 提交于 2021-02-08 14:16:20

问题


There something really weird happening in my MVC application that drives me crazy. On my MVC Page, after a user got selected, it's Login should be "rendered" twice on the HTML. Once in the form of

FrmNextStep('<Login>', ...
(where Model.SelectedUser.Login is used)

and once in the form of

<input id="SelectedLogin" name="SelectedLogin" value="<Login>" type="hidden">
(where "Model".SelectedLogin is used)

but the second one always stay blank. It's really weird because, despite the two call not being exactly the same, the return value should be.

if (Model.SelectedUser != null)
{
    <span>Some value</span>
    <script type="scriptADResultComplete">
    @{
        var script = String.Format(
            @"FrmNextStep('{0}', '{1}', '{2}');"
            , Model.SelectedUser.Login.Replace("'", @"\'")
            , Model.SelectedUser.FirstName.Replace("'", @"\'")
            , Model.SelectedUser.LastName.Replace("'", @"\'")
        );

        @Html.Raw(script);
    }
    </script>
}

<input type="hidden" name="hfAction" />
<input type="hidden" name="hfUserLogin" />
@Html.HiddenFor(m => m.CurrentPage, new { id = "hfCurrentPage" })
@Html.HiddenFor(m => m.SelectedLogin);


    private User selectedUser;
    public User SelectedUser
    {
        get
        {
            if (this.selectedUser == null)
            {
                this.selectedUser = this.AllUsers.FirstOrDefault(user => user.Selected) ?? User.DefaultUser;
            }

            if (this.selectedUser == User.DefaultUser)
            {
                return null;
            }

            return this.selectedUser;
        }
        set
        {
            this.AllUsers.ForEach(user => user.Selected = (user == value));

            this.selectedUser = null;
        }
    }

    public string SelectedLogin
    {
        get
        {
            return (this.SelectedUser ?? User.DefaultUser).Login;
        }
        set
        {
            this.SelectedUser = this.AllUsers.FirstOrDefault(user => user.Login == value);
        }
    }

And when I have debug the code,the only call to Selected Login during the "rendering" phase and return the correct login.

Is there any bug with Html.HiddenFor?


回答1:


Ok, it's actually a bug/faulty behaviour of Html.HiddenFor.
The idea of this possibility only came to my mind while I was writing my question.


I changed it into:

<input type="hidden" value="@Html.AttributeEncode(Model.SelectedLogin)" id="SelectedLogin" name="SelectedLogin" />

and it's working perfectly fine.

EDIT:

There's another workarround.

Call ModelState.Clear(); in the controler post action.
I'll use this option.

ModelState.Clear();

+

@Html.HiddenFor(m => m.SelectedLogin)



回答2:


I had this issue also, with the .cshtml executing twice while returning the page, and the second run having issues with null model objects.

Using @Serge's answer fixes the HiddenFor's, but then I also had issues with partials that can't be solved this way.

It turns out to be an intermittent issue, where the Controller method that invokes the view is setting ViewBag properties together with returning the view+model separately via protected internal ViewResult View(string viewName, object model);.

The project I'm working on has this all over the place, and on other controllers/views it works fine. But for the one I was maintaining, this null issue in the HiddenFor's was happening.

Anyway, I pulled all the ViewBag setters out of the controller, and moved them into NotMapped properties on the model object.

Once this was done the HiddenFor calls etc all started behaving again. So, don't mix your ViewBag and ViewModel kids.



来源:https://stackoverflow.com/questions/16816184/mvc-crazy-property-lose-its-value-does-html-hiddenfor-bug

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!