Reputation: 9108
Given the following class, what is your opinion on the best way to handle create/edit where Attributes.Count can be any number.
public class Product {
public int Id {get;set;}
public string Name {get;set;}
public IList<Attribute> Attributes {get;set;}
}
public class Attribute {
public string Name {get;set;}
public string Value {get;set;}
}
The user should be able to edit both the Product details (Name) and Attribute details (Name/Value) in the same view, including adding and deleting new attributes.
Handling changes in the model is easy, what's the best way to handle the UI and ActionMethod side of things?
Upvotes: 13
Views: 6215
Reputation: 4915
Look at Steve Sanderson’s blog post Editing a variable length list, ASP.NET MVC 2-style.
Your action method receives your native domain model Product
and stays pretty simple:
public ActionResult Edit(Product model)
Edit.aspx
<!-- Your Product inputs -->
<!-- ... -->
<!-- Attributes collection edit -->
<% foreach (Attribute attr in Model.Attributes)
{
Html.RenderPartial("AttributeEditRow", attr);
} %>
AttributeEditRow.ascx
Pay your attention to helper extension Html.BeginCollectionItem(string)
<% using(Html.BeginCollectionItem("Attributes")) { %>
<!-- Your Attribute inputs -->
<% } %>
Adding and editing of new attributes is possible too. See the post.
Upvotes: 14
Reputation: 9727
Use a custom Model Binder, and write the Action methods as you would normally:
ActionResult Edit(
int id,
[ModelBinder(typeof(ProductModelBinder))] Product product
) ...
In your ProductModelBinder, you iterate over the Form Collection values and bind to a Product entity. This keeps the Controller interface intuitive, and can help testing.
class ProductModelBinder : IModelBinder ...
Upvotes: 3
Reputation: 532465
Use the FormCollection and iterate through the key/value pairs. Presumably you can use a naming scheme that will allow you to determine which key/value pairs belong to your attribute set.
[AcceptVerbs( HttpVerb.POST )]
public ActionResult Whatever( FormCollection form )
{
....
}
Upvotes: 3
Reputation: 9108
Andrew,
I'm thinking something a little more difficult than tags. In this simple case a name / value pair .. color: Red; size: 10; material: cotton.
I think anything that could be used on that could extend to more complex. I.e. Adding a category and adding all its items on the same page. It's relatively easy to add another line using some jQuery, but what's the consensus on sending the info to the ActionMethod?
You can't code:
public ActionResult Whatever(stirng attr1Name, string attr2Name, string attr3Name ...
Also I don't think accepting this would work either:
public ActionResult Whatever(ILIst<Attribute> attributes, string productName ...
Upvotes: 0
Reputation: 1846
Depends on the experience you are looking to create for the user. I have implemented something similar for tagging content. In the model, Tags are represented as IList, but the UI shows a comma delimited list in a single text field. I then handle merging the items in the list into a string to populate the text field, and I split the input to put items back into the IList in the model.
In my DAL, I then deal with converting the List into LINQ entities, handle inserts and deletes, etc.
It isn't the most straight forward code, but it isn't too difficult to manage and it gives the user an expected interface.
I'm sure there are other ways to handle it but I would focus on what would work best for the user and then work out the mapping details based on that.
Upvotes: 0