开发者

How to pass nullable properties from ASP.NET view to Controller?

开发者 https://www.devze.com 2023-01-05 12:14 出处:网络
I\'ve been reading stackoverflow for a few years now, but this is the first time I really need to post a question as I can\'t seem to find a suitable answer anywhere.

I've been reading stackoverflow for a few years now, but this is the first time I really need to post a question as I can't seem to find a suitable answer anywhere.

The thing is, I want to pass an object (a LinqToSQL entity to be precise) to my View, allow the user to add some properties, and then post it back to save it.

My object, called Probation, has a few properties (id, forpost, forcomment, user, starting, hours) and some related entity references. The forpost and forcomment entities are nullable as a user can be probated for making an offensive post or an offensive comment. Please mind that forpost refers to an Idea entity, I don't know what I was thinking calling it a post.

So here's my controller logic:

        [Authorize(Roles = "Admin, Moderator")]
    public ActionResult ProbateUser(int? post, int? comment)
    {
        if (post != null)
        {
            Idea idea = irep.GetIdea(post ?? 0);
            Probation probation = new Probation
            {
                user = (Guid)idea.user,
                Idea = idea
            };
            return View(probation);
        }
        if (comment != null)
        {
            Comment rcomment = crep.GetComment(comment ?? 0);
            Probation probation = new Probation
            {
                user = rcomment.user,
                Comment = rcomment
            };
            return View(probation);
        }

        return View("NotFound");
    }

    [AcceptVerbs(HttpVerbs.Post)]
    [Authorize]
    public ActionResult ProbateUser(Probation probation, FormCollection values)
    {           
        try
        {
            probation.starting = DateTime.Now;
            rep.ProbateUser(probation);
            rep.Save();
            return RedirectToAction("Index");
        }
        catch
        {
            return View("NotFound");
        }
    }

}

And here's the view, using hidden fields to store the preset values:

        <fieldset>
        <legend>Fields</legend>
            <%: Html.Hidden("Idea", Model.Idea)%>
            <%: Html.Hidden("Comment", Model.Comment)%>
            <%: Html.Hidden("user", Model.user) %>
        <div class="editor-label">
            <%: Html.LabelFor(model => model.reason) %>
        </div>
        <div class="editor-field">
            <%: Html.TextAreaFor(model => model.reason) %>
            <%: Html.ValidationMessageFor(model => model.reason) %>
        </div>


        <div class="editor-label">
            <%: Html.LabelFor(model => model.hours) %>
        </div>
        <div class="editor-field">
            <%: Html.Te开发者_如何学运维xtBoxFor(model => model.hours) %>
            <%: Html.ValidationMessageFor(model => model.hours) %>
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>

Now my problem is, once the Probation object is posted back, the nullable fields forcomment and forpost are always null!

So to summarize: what is the correct way of passing objects with nullable properties from Controller->View->Controller? Pretty please?


It's because of the statelessness of MVC. If you want to those fields to retain its values, you will need to put them in hidden fields so then they are binded back during post, like such:

...
<legend>Fields</legend>
    <%: Html.Hidden("Idea", Model.Idea)%>
    <%: Html.Hidden("Comment", Model.Comment)%>
    <%: Html.Hidden("user", Model.user) %>
    <%: Html.Hidden("user", Model.ForPost) %>
    <%: Html.Hidden("user", Model.ForComment) %>
<div class="editor-label">
...


Okay, from what I've gathered from comments here and on other forums: there is simply no way to pass nullable fields and get them posted back. My workaround for this was building a partial Probation class that adds two non-nullable value fields to the Probation entity, and to use these to populate the fields after postback. As a (better) alternative, making ViewModels would work as well.

0

精彩评论

暂无评论...
验证码 换一张
取 消