Asp.Net MVC EditorTemplate Model is lost after Post
Asked Answered
E

1

6

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?

Eady answered 29/4, 2010 at 12:57 Comment(1)
Compare the submitted form in both cases using Firebug or Fiddler. It will be different. Fix that.Burmeister
P
1

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()
           );
}
Piranha answered 29/4, 2010 at 13:7 Comment(5)
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! :)Eady
Not if you define your own EditorTemplate in \Views\<Controller>\EditorTemplates\Piranha
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.Eady
Sure, give me a few minutes and I'll post a new answer with the code.Piranha
Instead <% Html.EditorFor(m => m); %> you should use <% Html.EditorForModel(); %>Simplistic

© 2022 - 2024 — McMap. All rights reserved.