2009-03-15 19 views
13

Ho riscontrato uno strano problema ... quando utilizzo UpdateModel() o TryUpdateModel(), tutto funziona correttamente. Quando provo a legarmi (ad esempio MyObject.FirstName = collection["FirstName"]), ottengo un errore "Object reference not set to an instance of an object".ASP.NET MVC - Html.Textbox() genera "Riferimento oggetto non impostato su un'istanza di un oggetto"

E 'un po' difficile da spiegare, quindi mi presenta il codice:

[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); 
      } 
     } 

Ecco la traccia dello stack:

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: 

risposta

22

ho trovato alcune informazioni qui: http://forums.asp.net/p/1396019/3006051.aspx

Se non si desidera utilizzare Builtin Modello rilegatura, quindi di utilizzare Bultin convalida (SanjaySutar desidera utilizzare), per ogni ModelError si aggiunge, è necessario aggiungere un ModelValue: ModelState.AddModelError ("Nome", "Nome errato ");

ModelState.SetModelValue ("Nome", ValueProvider ["Nome"]);

Così ho aggiornato il mio codice in questo 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 ragione per cui sto facendo questo è perché ho voluto a. avere tutte le convalide (o il più possibile) fatte nel mio oggetto business, compresi i campi obbligatori, e b. Volevo i miei messaggi nel riepilogo di convalida (ad esempio "FieldX è un campo obbligatorio." Invece di "È richiesto un valore."). Se c'è un modo migliore per farlo, vedi la mia altra domanda: ASP.NET MVC - Custom validation message for value types

+0

Grazie per l'intuizione! – John

+0

L'ho trovato su un modulo in cui stavo combinando due campi insieme e convalidando il risultato, ma volevo segnalare gli errori sui singoli campi (sorgente) ... Grazie - mi ha salvato una fronte livida! – GalacticCowboy

+4

Questo è il motivo per cui adoro lo stackoverflow, posso google le mie eccezioni e trovare la soluzione qui :) Grazie. –

0

Dove è enddate, startdate, e TrackID provenienti da? Questo non dovrebbe nemmeno essere compilato, ma forse sono solo stupido e non vedo le loro dichiarazioni. Sono sicuro che è appena fuori dalla vista, giusto?

Assicurati che tutti i valori del modulo contengano effettivamente delle informazioni.

+0

Le decelerazioni non sono state incluse (errore di copia e incolla). I valori dei moduli mancanti devono essere rilevati in GetRuleViolations() –

+0

Stavo principalmente pensando a evnt.IsActive = collection ["IsActive"]. Contains ("true"); linea. Se la raccolta ["IsActive"] è nullo si otterrebbe quell'errore a causa del tentativo di chiamare una funzione su un oggetto nullo. Sono contento di vederti fatto progressi, però! :) –

Problemi correlati