Reputation: 2754
I have these entities (there is many to many connection between them):
public class Post
{
public Guid PostId { get; set; }
public string Name { get; set; }
public virtual ICollection<Tag> Tags { get; set; }
}
public class Tag
{
public int TagId { get; set; }
public string Name { get; set; }
public virtual ICollection<Post> Posts { get; set; }
}
I'd like user, when he creates Post, to choose data from MultiSelectList and MultiSelectList to pass that data to Post.Tags. How can I do that ?
Upvotes: 5
Views: 9103
Reputation: 2989
I have something similar, a Product belongs to many Categories and a Category, has many products.
In my administrative view for creating new products, I am able to allow the user to select mutliple "tags" of categories that this product should be listed under.
Because of so many categories I tend to avoid multi select lists and use a sort of auto suggest with ajax to retrieve categories and populate them using a jQuery plugin such as TagIt.
But for simplicity you can use this in your Controller
public class HomeController : Controller
{
public ActionResult Create()
{
var tags = new List<Tag>()
{
new Tag() { TagId = 1, Name = "Planes", Posts = new Collection<Post>() },
new Tag() { TagId = 2, Name = "Cars", Posts = new Collection<Post>() },
new Tag() { TagId = 2, Name = "Boats", Posts = new Collection<Post>() }
};
ViewBag.MultiSelectTags = new MultiSelectList(tags, "TagId", "Name");
return View();
}
[HttpPost]
public ActionResult Create(Post post, int[] tags) // Tags is not case-sensative from model binder when html element name="tags" <-- array passed back to controller
{
// Find Tag from Database
// Attach tag entity to Post
// foreach(var tagId in tags)
// var tag = context.Tags.find(tagId)
// post.Tags.Add(tag);
// context.SaveChanges();
return RedirectToAction("Create");
}
}
And inside your View/Create.cshtml
@model MvcApplication1.Models.Post
<h2>Create</h2>
@using (Html.BeginForm("Create", "Home", FormMethod.Post))
{
<label>Name</label>
@Html.TextBoxFor(model => model.Name)
<label>Tags For Post</label>
@Html.ListBox("Tags", (MultiSelectList)ViewBag.MultiSelectTags)
<input type="submit" value="Submit Post"/>
}
all Selected tags:
Then when multiple are selected on posting back to controller you can see in debug that the model binder knows to send array back from html element name "tags"
Upvotes: 13