views:

40

answers:

1

MVC newbie question re binders. Supposing I have two strongly typed partial actions that happen to have a model attributes with the same name, and are rendered in the same containing page i.e.:

Class Friend {string Name {get; set ;} DateTime DOB {get; set ;}}
Class Foe {string Name {get; set ;} string ReasonForDislike {get; set ;}}

Both partials will have a line:

<%= Html.TextBoxFor(model => model.Name) %>

And associated controller actions:

public ActionResult SaveFriend(Friend friend)
public ActionResult SaveFoe(Foe foe)

My problem is that both will render on my containing page with the same id (of course, bad for lots of reasons). I’m aware of the [Bind] attribute that allows me add a prefix, resulting in code:

public ActionResult SaveFriend([Bind(Prefix = “friend”)] Friend friend)
<%= Html.TextBox("friend.Name", Model. Name) %> //Boo, no TextBoxFor :(

But this still doesn’t cut it. I can just about tolerate the loss of the strongly typed TextBoxFor helpers but I’ve yet to get clientside validation to work with prefixes: I’ve tried:

<%= Html.ValidationMessage("friend.Name") %>

...and every other variant I can think of.

I seem to need the model to be aware of the prefix in both directions but bind only applies when mapping the inbound request. It seems (to me) a common scenario but I’m struggling to find examples out there. What am I missing!

Thanks in advance.

+1  A: 

The prefix is there so you can wrap your objects in an "outer" ViewModel.

Suppose we have:

public class MyViewModel
{
   public Friend friend;
   public Foe foe;
}

If you use this class as your ViewModel and as the base of your strongly-typed Views, then your strongly-typed Textboxes will be named thusly:

friend.Name
foe.Name

You can then use the Prefix attribute you refer to in your question to disambiguate between your Friend and Foe classes.

Dave Swersky
Many thanks, yes the Bind attribute is only for mapping requests, I felt it was wrong but was clutching at straws at that point! I hadn’t considered creating a wrapper class to influence the rendering. I must admit I’m not entirely comfortable creating redundant wrappers for domain objects just to get the views to work but it certainly solves my immediate problem. It would be nice to be able to specify a prefix in the model that applied to both requests and responses.Thanks for getting me up running again!
Vman
Glad I could help. FYI- You don't *have* to create ViewModels, but it works so much better with MVC that it kinda forces you to write better code. The problem isn't the style, it's the lack of tooling. ViewModel creation shouldn't be such a labor-intensive process, but it's still early days (and versions) with ASP.NET MVC...
Dave Swersky