2009-03-15 18 views
13

He encontrado un problema extraño ... cuando uso UpdateModel() o TryUpdateModel(), todo funciona bien. Cuando intento enlazarme (por ejemplo, MyObject.FirstName = collection["FirstName"]), aparece un error "Object reference not set to an instance of an object".ASP.NET MVC - Html.Textbox() arroja "Referencia de objeto no establecida en una instancia de un objeto"

Es un poco difícil de explicar, así que voy a presentar el código:

[HandleError] 
    [AcceptVerbs(HttpVerbs.Post)] 
    public ActionResult Create(FormCollection collection) 
    { 
     try 
     { 
      Model.Event evnt = new Redline.RedlineTimeAttack.Model.Event(); 

      //When this is uncommented everything works fine. 
      //TryUpdateModel<Model.Event>(evnt); 

      //this will eventually lead to problems 
      evnt.Description = collection["Description"]; 
      evnt.EndDate = enddate; 
      evnt.EventName = collection["EventName"]; 
      evnt.IsActive = collection["IsActive"].Contains("true"); 
      evnt.StartDate = startdate; 
      evnt.TrackId = trackId; 
      evnt.WebContent = collection["WebContent"]; 


      if (!evnt.IsValid) 
      { 
       foreach (var error in evnt.GetRuleViolations()) 
       { 
       ModelState.AddModelError(error.PropertyName, error.ErrorMessage); 
       } 
      } 

      //If there are no validation issues then no problem, redirecttoaction 
      //works properly 
      if (ModelState.IsValid) 
      { 
       model.Events.InsertOnSubmit(evnt); 
       model.SubmitChanges(); 
       ViewData["ControlMode"] = "Edit"; 
       return RedirectToAction("Edit"); 
      } 
      else //returning to View so that user can correct issues causes a null reference error in the view (bombs at first Html.Textbox("ControlName")) 
      { 
       ViewData["Tracks"] = GetTracks(); 
       return View("Create", evnt); 
      } 
     } 

Aquí está el seguimiento de la pila:

System.NullReferenceException was unhandled by user code 
Message="Object reference not set to an instance of an object." 
Source="System.Web.Mvc" 
StackTrace: 
    at System.Web.Mvc.HtmlHelper.GetModelStateValue(String key, Type destinationType) 
    at System.Web.Mvc.Html.InputExtensions.InputHelper(HtmlHelper htmlHelper, InputType inputType, String name, Object value, Boolean useViewData, Boolean isChecked, Boolean setId, Boolean isExplicitValue, IDictionary`2 htmlAttributes) 
    at System.Web.Mvc.Html.InputExtensions.TextBox(HtmlHelper htmlHelper, String name, Object value, IDictionary`2 htmlAttributes) 
    at System.Web.Mvc.Html.InputExtensions.TextBox(HtmlHelper htmlHelper, String name) 
    at ASP.views_event_create_aspx.__RenderContent2(HtmlTextWriter __w, Control parameterContainer) in d:\TFSProjects\Redline Time Attack\Main\Source\Redline.RedlineTimeAttack.Web\Views\Event\Create.aspx:line 18 
    at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) 
    at System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) 
    at System.Web.UI.Control.Render(HtmlTextWriter writer) 
    at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) 
    at System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) 
    at System.Web.UI.Control.RenderControl(HtmlTextWriter writer) 
    at ASP.views_shared_site_master.__Render__control1(HtmlTextWriter __w, Control parameterContainer) in d:\TFSProjects\Redline Time Attack\Main\Source\Redline.RedlineTimeAttack.Web\Views\Shared\Site.Master:line 29 
    at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) 
    at System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) 
    at System.Web.UI.Control.Render(HtmlTextWriter writer) 
    at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) 
    at System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) 
    at System.Web.UI.Control.RenderControl(HtmlTextWriter writer) 
    at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) 
    at System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) 
    at System.Web.UI.Page.Render(HtmlTextWriter writer) 
    at System.Web.Mvc.ViewPage.Render(HtmlTextWriter writer) 
    at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) 
    at System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) 
    at System.Web.UI.Control.RenderControl(HtmlTextWriter writer) 
    at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) 
InnerException: 

Respuesta

22

me pareció una idea aquí: http://forums.asp.net/p/1396019/3006051.aspx

Si no desea utilizar Integrados Modelo encuadernación, luego de usar Bultin Validación (SanjaySutar quieren usar), para cada ModelError se agrega, necesitará agregar un valor de modelo: ModelState.AddModelError ("Nombre", "Nombre malo");

ModelState.SetModelValue ("Nombre", ValueProvider ["Name"]);

Así que actualizan el código de este modo:

ModelState.SetModelValue("Description", new ValueProviderResult(ValueProvider["Description"].AttemptedValue, collection["Description"], System.Globalization.CultureInfo.CurrentCulture)); 
ModelState.SetModelValue("EventName", new ValueProviderResult(ValueProvider["EventName"].AttemptedValue, collection["EventName"], System.Globalization.CultureInfo.CurrentCulture)); 
ModelState.SetModelValue("EndDate", new ValueProviderResult(ValueProvider["EndDate"].AttemptedValue, collection["EndDate"], System.Globalization.CultureInfo.CurrentCulture)); 
ModelState.SetModelValue("StartDate", new ValueProviderResult(ValueProvider["StartDate"].AttemptedValue, collection["StartDate"], System.Globalization.CultureInfo.CurrentCulture)); 
ModelState.SetModelValue("TrackId", new ValueProviderResult(ValueProvider["TrackId"].AttemptedValue, collection["TrackId"], System.Globalization.CultureInfo.CurrentCulture)); 
ModelState.SetModelValue("WebContent", new ValueProviderResult(ValueProvider["WebContent"].AttemptedValue, collection["WebContent"], System.Globalization.CultureInfo.CurrentCulture)); 

La razón por la que estoy haciendo esto es porque quería una. tener toda la validación (o tanto como sea posible) en mi Business Object, incluidos los campos obligatorios, y b. Quería mis propios mensajes en el resumen de validación (por ejemplo, "FieldX es un campo obligatorio" en lugar de "Se requiere un valor"). Si hay una mejor manera de hacerlo, consulte mi otra pregunta: ASP.NET MVC - Custom validation message for value types

+0

¡Gracias por la información! – John

+0

Encontré esto en un formulario en el que combinaba dos campos y validaba el resultado, pero quería informar los errores en los campos individuales (fuente) ... Gracias - ¡me salvó una frente lastimada! – GalacticCowboy

+4

Es por eso que amo stackoverflow, puedo buscar mis excepciones en google y encontrar la solución aquí :) Gracias. –

0

Cuando se enddate, startdate, y TrackID procedentes de? Esto ni siquiera debería compilar, pero tal vez solo soy tonto y no veo sus declaraciones. Estoy seguro de que está en algún lugar fuera de la vista, ¿verdad?

Asegúrate de que todos los valores de formulario realmente tengan también algo en ellos.

+0

Las desaceleraciones no se incluyeron (error de copiar y pegar). Los valores de formulario faltantes deberían capturarse en GetRuleViolations() –

+0

. Estaba pensando principalmente en la colección evnt.IsActive = ["IsActive"]. Contains ("true"); línea. Si collection ["IsActive"] es nulo, obtendría ese error porque intenta llamar a una función en un objeto nulo. ¡Me alegra ver que progresaste! :) –

Cuestiones relacionadas