[英]ASP.NET MVC DropDownList NullReferenceException
Im having a problem with my dropDownList giving me a NullReferenceException and I don't know why. 我有一个问题,我的dropDownList给我一个NullReferenceException,我不知道为什么。
I want to post a post where you can choose with the DropDownList which Category it belongs to. 我想发布一个帖子,您可以使用DropDownList选择它所属的类别。
Here is some of my code: 这是我的一些代码:
PostModel PostModel
public class Post
{
[Key]
public int PostID { get; set; }
[Display(Name = "Idea Title")]
public String Title { get; set; }
[Display(Name = "Description")]
public String DescText { get; set; }
[Display(Name = "Votes")]
public int Votes { get; set; }
[Display(Name = "Comments")]
public int CommentCount { get; set; }
[Display(Name = "Posted:")]
[DataType(DataType.DateTime)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime CreatedDate { get; set; }
[Display(Name = "Last Edited:")]
[DataType(DataType.DateTime)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime? EditedDate { get; set; }
public String UserName { get; set; }
public virtual Status Status { get; set; }
public virtual Category Category { get; set; }
public virtual Department Department { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
}
PostViewModel PostViewModel
public class PostCreateViewModel
{
[Required]
[Display(Name = "Title")]
[MinLength(10, ErrorMessage = "The title must be at least 10 characters long.")]
[StringLength(100, ErrorMessage = "The title cannot be longer than 100 characters.")]
public String Title { get; set; }
[Required]
[DataType(DataType.MultilineText)]
[MinLength(50, ErrorMessage = "The description of your idea should be at least 50 characters long.")]
public String DescText { get; set; }
[Required]
[Display(Name = "Category")]
public int SelectedCategoryId { get; set; }
public IEnumerable<SelectListItem> Categories { get; set; }
}
CategoryModel CategoryModel
public class Category
{
[Key]
public int CategoryID { get; set; }
[Display(Name = "Category Name")]
public String CategoryName { get; set; }
}
public class DbCategories
{
private IdeaContext context = new IdeaContext();
public List<Category> GetCategories()
{
return context.Categories.ToList();
}
}
PostController UPDATED PostController UPDATED
private IEnumerable<SelectListItem> GetCategories()
{
var dbCategories = new DbCategories();
var categories = dbCategories
.GetCategories()
.Select(x =>
new SelectListItem
{
Value = x.CategoryID.ToString(),
Text = x.CategoryName
});
return new SelectList(categories, "Value", "Text");
}
[HttpGet]
public ActionResult Create()
{
var model = new PostCreateViewModel { Categories = GetCategories() };
return View(model);
}
[HttpPost]
public ActionResult Create(PostCreateViewModel model)
{
model.Categories = GetCategories();
if (ModelState.IsValid)
{
var post = new Post();
// From ViewModel
post.Title = model.Title;
post.DescText = model.DescText;
var dbCategories = new DbCategories();
var categories = dbCategories.GetCategories();
post.Category = categories.FirstOrDefault(x => x.CategoryID == model.SelectedCategoryId);
// Controller created
post.CreatedDate = DateTime.Now;
post.Votes = 0;
post.CommentCount = 0;
post.Status.StatusName = "Active";
post.Department = null;
post.UserName = User.Identity.Name;
context.Posts.Add(post);
context.SaveChanges();
return RedirectToAction("Index");
}
else
{
return View();
}
}
And my View 而我的观点
@model WebApplication3.Models.ViewModels.PostCreateViewModel
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-group top-space-large">
@Html.LabelFor(model => model.Title, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Title, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Title, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.SelectedCategoryId, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(m => m.SelectedCategoryId, Model.Categories, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.SelectedCategoryId, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group top-space-large">
@Html.LabelFor(model => model.DescText, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.DescText, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.DescText, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group top-space-large">
<button type="submit" class="btn btn-default">Submit</button>
</div>
}
Stack Exception 堆栈异常
System.NullReferenceException was unhandled by user code
HResult=-2147467261
Message=Object reference not set to an instance of an object.
Source=App_Web_jqgoppva
StackTrace:
at ASP._Page_Views_Post_Create_cshtml.Execute() in \\etj\My Documents\Visual Studio 2013\Projects\WebApplication3\WebApplication3\Views\Post\Create.cshtml:line 24
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy()
at System.Web.Mvc.WebViewPage.ExecutePageHierarchy()
at System.Web.WebPages.StartPage.RunPage()
at System.Web.WebPages.StartPage.ExecutePageHierarchy()
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)
at System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance)
at System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer)
at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
InnerException:
Why is this happening? 为什么会这样? When I try to post the form I get "Object reference not set to an instance of an object" in the View on the line for the DropDownList.
当我尝试发布表单时,我在DropDownList行的视图中得到“对象引用未设置为对象的实例”。 The context.Categories is not empty.
context.Categories不为空。 It contains "Web" with id 28 and "Environment" with id 31.
它包含ID为28的“Web”和ID为31的“Environment”。
The only reason I see this to happen is because on POST
action you want to use Model.Categories
which is not persisted. 我发现这种情况的唯一原因是因为在
POST
操作中你想使用不持久的Model.Categories
。 You have to call again the GetCatgories()
method in action Create
. 您必须在操作
Create
再次调用GetCatgories()
方法。
You get the NullReference
exception because post.Category
is null
and you can't access a property of a null
object, post.Category.CategoryID = model.SelectedCategoryId;
你得到
NullReference
异常因为post.Category
为null
而你无法访问null
对象的属性, post.Category.CategoryID = model.SelectedCategoryId;
. 。 You have to query the
Category
from database based on the SelectedCategoryId
. 您必须根据
SelectedCategoryId
从数据库中查询Category
。
[HttpPost]
public ActionResult Create(PostCreateViewModel model)
{
model.Categories = GetCategories(); // call again, Categories don't persist in a POST.
if (ModelState.IsValid)
{
var post = new Post();
// ...
post.Category = context.Categories.FirstOrDefault(x => x.CategoryId == model.SelectedCategoryId);
// ...
return RedirectToAction("Index");
}
return View(model);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.