Reputation: 1050
I'm trying to make a simple news system in MVC4. I'm very new at it, and I have a simple News base class that looks like this:
NewsPost:
public class NewsPost
{
public virtual int Id { get; set; }
public virtual string Subject { get; set; }
public virtual string Content { get; set; }
}
It's then attached to a category class like so:
NewsCategory:
public class NewsCategory
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual ICollection<NewsPost> NewsPosts { get; set; }
}
I then have a controller for creating these NewsPosts:
NewsController:
private readonly INewMvcSiteDataSource _db;
public NewsController(INewMvcSiteDataSource db)
{
_db = db;
}
[HttpGet]
public ActionResult Create()
{
var model = new CreateNewsViewModel();
model.Categories = new SelectList(_db.NewsCategories, "Id", "Name");
return View(model);
}
[HttpPost]
public ActionResult Create(CreateNewsViewModel newsModel)
{
if (ModelState.IsValid)
{
int id = int.Parse(newsModel.SelectedCategories.Single(f => f.Selected).Value);
}
return View(newsModel);
}
And lastly, to facilitate with creating the NewsPost, I use a CreateNewsViewModel, like so:
CreateNewsViewModel:
public class CreateNewsViewModel
{
[Required]
public string Subject { get; set; }
[Required]
public string Content { get; set; }
public SelectList Categories { get; set; }
public SelectList SelectedCategories { get; set; }
}
My view looks like this:
Create.cshtml:
@model NewMvcSite.Models.CreateNewsViewModel
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>CreateNewsViewModel</legend>
<div class="editor-label">
@Html.LabelFor(model => model.Subject)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Subject)
@Html.ValidationMessageFor(model => model.Subject)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Content)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Content)
@Html.ValidationMessageFor(model => model.Content)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Categories)
</div>
<div class="editor-field">
@Html.DropDownListFor(model => model.Categories, Model.SelectedCategories)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
For some reason, my viewmodel isn't returned when I click the submit button to create the newspost, and since there is no parameterless constructor for [HttpPost] Create action, it fails with "No parameterless constructor defined for this object."
I've been trying going through other posts here stating the same problem, but I fail to see the connection between what they are doing and what I am doing. I hope there is someone out there who can help me.
Thank you.
Upvotes: 0
Views: 3567
Reputation: 1050
I found the solution.
I had to change the ViewModel to this:
public IEnumerable<SelectListItem> Categories { get; set; }
public int SelectedCategoryId { get; set; }
I changed the controller to:
var model = new CreateNewsViewModel
{
Categories = new SelectList(_db.NewsCategories, "Id", "Name")
};
And changed View to this:
@Html.DropDownListFor(x => x.SelectedCategoryId, Model.Categories)
Upvotes: 0
Reputation: 2061
If you want to select category from drop down list, first of all you should add property to your model to hold Id of selected category. Something like this (property Category):
public class CreateNewsViewModel
{
[Required]
public string Subject { get; set; }
[Required]
public string Content { get; set; }
public SelectList Categories { get; set; }
public SelectList SelectedCategories { get; set; }
public int Category { get; set; }
}
after that, you should change code to filling model.Category to this:
model.Categories = new SelectList(categories, "Id", "Name", model.Category);
and than, in your view, editor for Category should look like this:
<div class="editor-field">
@Html.DropDownListFor(m => m.Category, Model.Categories);
</div>
Upvotes: 1
Reputation: 17288
model.Categories = new SelectList(_db.NewsCategories, "Id", "Name");
At this line you fill Categories
property
@Html.DropDownListFor(model => model.Categories, Model.SelectedCategories)
Here you trying create select
with Categories
name and SelectedCategories
items
int id = int.Parse(newsModel.SelectedCategories.Single(f => f.Selected).Value);
Here you trying get selected item, BUT on form submit you only sending one number, not list. One of your SelectList
must be int
Upvotes: 0