If Scott Allen can make it work ... why can't I? Should be a simple drop down list - MVC3
I have been wrestling with what should be a very simple thing for weeks now. I simply want to create a dropdownlist in asp.net mvc 3 razor html page and I want the data for the dropdownlist to come from a model.
My Model is as follows which is in the Models.Project namespace.
public class Project
{
public Project()
{
CategoryId = 0;
Name = "";
Description = "";
//Categories = new Dictionary<int, string>();
Entities _db = new Entities(); //ef4
CateogoriesList = from c in _db.Categories
orderby c.Name
select c.Name;
}
public int CategoryId { get; set; }
[Required]
[DataType(DataType.Text)]
[Display(Name = "Project Name")]
public string Name { get; set; }
[Required]
[DataType(DataType.MultilineText)]
[Display(Name = "Project Description")]
public string Description { get; set; }
public IQueryable<string> CateogoriesList;
}
My Controller action is as follows
public ActionResult Create()
{
Models.Project.Project proj = new 开发者_Python百科Models.Project.Project();
return View(proj);
}
My Razor view has the following relevant code ...
@{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@model Models.Project.Project
@using (Html.BeginForm())
{
@Html.ValidationSummary(true);
<fieldset>
<legend>Submit Your Request</legend>
<div class="editor-label">@Html.LabelFor( Model => Model.CateogoriesList )</div>
<div class="editor-field">
@Html.DropDownList("Category", new SelectList( Model.CateogoriesList ) )
</div>
</fieldset>
<p><input type="submit" value="Send for RFP" /></p>
}
The problem is that I get the following error ...
Compiler Error Message: CS0135: 'Model' conflicts with the declaration 'System.Web.Mvc.WebViewPage<TModel>.Model'
I saw the following clip make it work with the ViewBag ... and I don't understand why it won't work when I include the list in the model.
http://www.pluralsight-training.net/microsoft/players/PSODPlayer.aspx?author=scott-allen&name=mvc3-building-data-i&mode=live&clip=0&course=aspdotnet-mvc3-intro
I have also seen that there are a lot of people that seem to have trouble with this simple task but in my googling ... I haven't come across anyone with the same error in trying to create a drop down list.
I would appreciate any suggestions that you or anyone may have. The only thing that I've come up with is that the SelectList
constructor takes a parameter of type System.Collections.IEnumerable
and what I'm trying to pass it is System.Collections.Generic.IEnumerable
... or something close to it ... and I don't know how to cast it appropriately ... though I don't think I should have to ... if it works with a viewbag as the means of transportation why doesn't it work with the model as the means of transportation?
Thanks,
EDIT:======================
The problem was to do with the type of object the selectList constructor would accept. For some reason it wouldn't accept a generic IQueryable but when I cast the result from the entity framework using the cast extension method toArray it suddenly worked.
So my model becomes ...
public class Project { public Project() {
Riebro.RiebroEntities _db = new Riebro.RiebroEntities();
CategoriesList = (from c in _db.Categories
orderby c.Name
select c.Name).ToArray<string>();
}
[Display(Name = "Choose a category")]
public string[] CategoriesList;
}
note the .ToArray on the end of the query and then suddenly
@Html.DropDownList("Category", new SelectList(Model.CategoriesList))
works. Though I am going to point out the Model keyword here seems to be required.
In your view you use:
@model Models.Project.Project
whereas in your controller action you pass:
public ActionResult Create()
{
Riebro.Models.Project.Project proj = new Riebro.Models.Project.Project();
return View(proj);
}
Notice the difference? Models.Project.Project
vs Riebro.Models.Project.Project
. You don't seem to be using the same type on your controller as on your view.
Also notice that it is bad practice to use namespace names that contain the name of a class.
Another remark is about using the Model keyword in lambda expressions:
@Html.LabelFor(Model => Model.CateogoriesList)
You shouldn't use this keyword. Replace Model with something else.
See your code, what's that? that's the reason cause the error.
<div class="editor-label">@Html.LabelFor( Model => Model.CateogoriesList )</div>
correct one
<div class="editor-label">@Html.LabelFor( Model => Model.CategoryId )</div>
@using (Html.BeginForm())
{
@Html.ValidationSummary(true);
<fieldset>
<legend>Submit Your Request</legend>
<div class="editor-label">@Html.LabelFor(x=>x.CategoryId )</div>
<div class="editor-field">
@Html.DropDownList("Category", new SelectList(Model.CateogoriesList) )
</div>
</fieldset>
<p><input type="submit" value="Send for RFP" /></p>
}
Here is my simulation of your entity. I just add another CategoriesList2 which use to simulate the IQueryable object, but it's still working.
public class Project {
public Project() {
CategoryId = 0;
Name = "";
Description = "";
//Categories = new Dictionary<int, string>();
//Entities _db = new Entities(); //ef4
//CateogoriesList = from c in _db.Categories
// orderby c.Name
// select c.Name;
//IQueryable<string> categoriesList = (new string[] { }).AsQueryable();
CateogoriesList = new string[] { "abc", "def", "hij", "klm" };
CategoriesList2 = (new string[] { "abc", "def", "hij", "klm" }).AsQueryable();
}
public int CategoryId { get; set; }
[Required]
[DataType(DataType.Text)]
[Display(Name = "Project Name")]
public string Name { get; set; }
[Required]
[DataType(DataType.MultilineText)]
[Display(Name = "Project Description")]
public string Description { get; set; }
public string[] CateogoriesList;
public IQueryable<string> CategoriesList2;
}
Here is the view by using the IQueryable categories list
@model MvcApplication3.Models.Project
@using (Html.BeginForm())
{
@Html.ValidationSummary(true);
<fieldset>
<legend>Submit Your Request</legend>
<div class="editor-label">@Html.LabelFor(x=>x.CategoryId )</div>
<div class="editor-field">
@Html.DropDownList("Category", new SelectList(Model.CategoriesList2) )
</div>
</fieldset>
<p><input type="submit" value="Send for RFP" /></p>
}
You are using the reserved keyword Model in your lambda expression
<div class="editor-label">@Html.LabelFor( Model => Model.CateogoriesList )</div>
try this
<div class="editor-label">@Html.LabelFor( m=> m.CateogoriesList )</div>
精彩评论