7

I'm still relatively new to ASP.NET MVC 3, and I have a conceptual question for those of you with more experience here.

Lets say for (simple) example I have a signup form for an event. The form would show the name of the event, and a text box where the user could enter their name. The ViewModel would look something like this:

public class SignupFormViewModel {
   public string EventName { get; set; }
   [Required]
   public string VolunteerName { get; set; }
}

The Razor view might look something like this:

<h2>Sign up for @Model.EventName</h2>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<div class="editor-field">
    @Html.EditorFor( model => model.VolunteerName )
    @Html.ValidationMessageFor( model => model.VolunteerName  )
</div>
}

If the user submits the form back to the server and the ModelState is invalid, we return the original View and pass back the Model so we can display the errors. (we're assuming for this example that this is an error not handled on the client)

The trouble is that in my example view shown above, the EventName is not submitted with the form data. I only want to use it for page content, not a form field. But if I have to go back and display validation errors to the user, I've lost the EventName property.

So what are my options for preserving this non-form-field item through a post which comes back to the same view?

I know I can make a hidden field to hold the EventName property, but there's just something that doesn't smell right about being forced to put every non-form-field property into a hidden field. I also know that I could go into the HttpPost action in my controller, and reload that data back into the Model before returning the view, but that feels clunky as well.

I guess I have a good understanding of the basic ways to do this, but I was wondering if there was a better way or best practice that felt cleaner... or if I just have to learn to deal with it :-)

Thanks

4

1 回答 1

7

为此使用隐藏字段没有任何问题。当您实际上不希望它们显示为表单字段时,这是一种在请求上持久化事物的非常传统的方式。

请记住,HTTP 是无状态的,因此在页面上放置一些内容并在 POST 请求中再次拾取它实际上是一种在多个请求中持久化数据的更一致的方式,而不是使用另一种产生有状态错觉的机制。

如果您觉得这使您的标记过于混乱,您可以尝试将值放入TempData初始 GET 请求的集合中,该请求仅在下一个请求期间存在,允许您在下一个控制器操作中获取它:

TempData["MyVar"] = model.EventName

但是,如果您希望将其保留在模型中,就像传统的(并且 - 在我看来 - 最好的)方式一样,隐藏字段仍然是要走的路:

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

为了进一步阅读,您还可以考虑cookiesession state,尽管它们都不会将值保留在模型中。然而,这两种机制都有其局限性,我在另一个答案中对此进行了概述。

于 2013-06-04T18:05:37.223 回答