Can someone explain why the model object is null. I checked the post values coming across the wire and all of them are populated.
Using VS2010 Beta 2,WinXp SP2,however this works in VS2008 ??!!
Yellow screen of death message
Server Error in '/' Application. Object reference not set to an instance of an object. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
Source Error:
Line 17: <p> Line 18: <label for="id">id:</label> Line 19: <%= Html.TextBox("id", Model.id) %> <--Error Line 20: <%= Html.ValidationMessage("id", "*") %> Line 21: </p>
Controller Code
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Contact contactToEdit)
{
if (contactToEdit.FirstName.Trim().Length == 0)
ModelState.AddModelError("FirstName", "First name is required.");
if (contactToEdit.Lastname.Trim().Length == 0)
ModelState.AddModelError("LastName", "Last开发者_开发技巧 name is required.");
if (contactToEdit.Phone.Length > 0 && !Regex.IsMatch(contactToEdit.Phone, @"((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}"))
ModelState.AddModelError("Phone", "Invalid phone number.");
if (contactToEdit.Email.Length > 0 && !Regex.IsMatch(contactToEdit.Email, @"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$"))
ModelState.AddModelError("Email", "Invalid email address.");
if (!ModelState.IsValid)
return View();
try
{
// TODO: Add update logic here
var con = (from c in _entities.Contacts
where c.id == contactToEdit.id
select c).FirstOrDefault();
_entities.ApplyCurrentValues(con.EntityKey.EntitySetName, contactToEdit);
_entities.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
Snippet of View code
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<JQGallery.Models.Contact>" %>
...
<%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %>
<% using (Html.BeginForm()) {%>
<fieldset>
<legend>Fields</legend>
<p>
<label for="id">id:</label>
<%= Html.TextBox("id", Model.id) %>
<%= Html.ValidationMessage("id", "*") %>
</p>
<p>
<label for="FirstName">FirstName:</label>
<%= Html.TextBox("FirstName", Model.FirstName) %>
<%= Html.ValidationMessage("FirstName", "*") %>
</p>
<p>
...
The Model object is null because you're not setting it. In your POST controller method, neither of the View results you return is setting a model (after the if (!ModelState.IsValid)
line and in your catch
block). In both those cases, you need to reload your model from somewhere so the view can redisplay its data.
Do you have a controller action that accepts non-post verbs and sets up the model for your view? The model will be null if you navigate directly to the view without an Action method that responds to a GET request and populates the model.
For example, your regular action could be something like
//
// Reponds to: GET /Contact/Edit/5
public ActionResult Edit(int id)
{
Contact contactToEdit = GetContactFromDatabase(id);
return View(contactToEdit);
}
I can't see anything wrong with the POST action, but you do need a corresponding GET action to set up the form for you.
EDIT: One other thing you might want to consider since you're using ASP.NET MVC built-in model binders is that you should probably exclude the ID (or any sensitive field that the user shouldn't logically be able to change) from being changed and actually remove it from the form (or at least make it un-editable). You can do that with an attribute on the incoming contact object, like this:
//
// Reponds to: POST /Contact/Edit/5
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit([Bind(Exclude="id")] Contact contactToEdit)
{
// ... do edit logic/validation stuff
}
精彩评论