views:

267

answers:

1

I have a controller with two simple Methods:

UserController Methods:

[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Details(string id)
{
 User user = UserRepo.UserByID(id);

 return View(user);
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Details(User user)
{
 return View(user);
}

Then there is one simple view for displaying the details:

<% using (Html.BeginForm("Details", "User", FormMethod.Post))
   {%>
 <fieldset>
  <legend>Userinfo</legend>
  <%= Html.EditorFor(m => m.Name, "LabelTextBoxValidation")%>
  <%= Html.EditorFor(m => m.Email, "LabelTextBoxValidation")%>
  <%= Html.EditorFor(m => m.Telephone, "LabelTextBoxValidation")%>
 </fieldset>
 <input type="submit" id="btnChange" value="Change" />
<% } %>

As you can see, I use an editor template "LabelTextBoxValidation":

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %>
<%= Html.Label("") %>
<%= Html.TextBox(Model,Model)%>
<%= Html.ValidationMessage("")%>

Showing user information is no problem. The view renders perfectly user details. When I submit the form, the object user is lost. I debugged on the row "return View(User);" in the Post Details method, the user object is filled with nullable values. If I dont use the editor template, the user object is filled with correct data. So there has to be something wrong with the editor template, but can't figure out what it is. Suggestions?

+1  A: 

I would re-architect a little bit - change your LabelTextBoxValidation editor to an Html helper, and then make one EditorTemplate for your data model. That way you could do something like this:

<% using (Html.BeginForm("Details", "User", FormMethod.Post))
{%>
  <fieldset>
   <legend>Userinfo</legend>
   <% Html.EditorFor(m => m); %>
  </fieldset>
  <input type="submit" id="btnChange" value="Change" />
<% } %>

And your editor template would be something like:

<%= Html.ValidatedTextBoxFor(m => m.Name); %>
<%= Html.ValidatedTextBoxFor(m => m.Email); %>
<%= Html.ValidatedTextBoxFor(m => m.Telephone); %>

where ValidatedTextBoxFor is your new html helper. To make that, it would be fairly easy:

public static MvcHtmlString ValidatedTextBoxFor<T>(this HtmlHelper helper, Expression thingy)
{
     // Some pseudo code, Visual Studio isn't in front of me right now
     return helper.LabelFor(thingy) + helper.TextBoxFor(thingy) + helper.ValidationMessageFor(thingy);
}

That should set the names of the form fields right I believe, as that seems like the source of the problem.

EDIT: Here is the code that should help you out:

public static MvcHtmlString ValidatedTextBoxFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
{
    return MvcHtmlString.Create(
           html.LabelFor(expression).ToString() +
           html.TextBoxFor(expression).ToString() +
           html.ValidationMessageFor(expression).ToString()
           );
}
Tejs
The line Html.EditorFor( m => m) renders all members of the model, that's not what I want. I just want to render three members of the user class. But the new html helper looks good, thanks! :)
Farrell
Not if you define your own EditorTemplate in \Views\<Controller>\EditorTemplates\
Tejs
Tejs: To make that, it would be fairly easy: Could you be more clear on how to create such a HtmlHelper? I am trying to create one with such a structure, but I fail to do so.
Farrell
Sure, give me a few minutes and I'll post a new answer with the code.
Tejs
Thank you very much!
Farrell