2017-08-25 1 views
0

Nach POST eines ActionController bekomme ich die große Objektreferenz nicht auf eine Instanz eines Objekts Fehler eingestellt.ASP.NET MVC - Null-Objekt in ViewModel auf POST

Grundsätzlich muss ich die ID der userRequest mit der requestResponse gespeichert werden. (Foreign Key hier)

Hier ist der Code.

Ansichtsmodell:

public class RequestResponseViewModel 
{ 
    public Models.Request userRequest { get; set; } 

    public Models.RequestResponse requestResponse { get; set; } 

} 

Ausblick: Im Debug hier gibt es Wert in model.userRequest.ID

@model UserRequests.ViewModels.RequestResponseViewModel 

    @{ 
    ViewBag.Title = "Create"; 
    } 

    <h2>Admin Response to Request</h2> 

    @using (Html.BeginForm()) 
    { 
    @Html.AntiForgeryToken() 

    <div class="form-horizontal"> 
     <hr /> 
     @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 
     <div class="form-group"> 
      @Html.LabelFor(model => model.requestResponse.Response, 
    htmlAttributes: new { @class = "control-label col-md-1" }) 
      <div class="col-md-10"> 
       @Html.TextAreaFor(model => model.requestResponse.Response, new { 
    @class = "form-control", @rows = 5 }) 
       @Html.ValidationMessageFor(model => 
    model.requestResponse.Response, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     <div class="form-group"> 
       @Html.LabelFor(model => model.userRequest.ID, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-2"> 

       @Html.DisplayFor(model => model.userRequest.ID)    
       @Html.ValidationMessageFor(model => model.userRequest.ID, "", new { @class = "text-danger" }) 
      </div> 
      @Html.LabelFor(model => model.requestResponse.Author, htmlAttributes: new { @class = "control-label col-md-1" }) 
      <div class="col-md-3"> 
       @Html.EditorFor(model => model.requestResponse.Author, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.requestResponse.Author, "", new { @class = "text-danger" }) 
      </div> 
      @Html.LabelFor(model => model.requestResponse.CreateDate, htmlAttributes: new { @class = "control-label col-md-1" }) 
      <div class="col-md-3"> 
       <h5>@DateTime.Now</h5> 
       @Html.ValidationMessageFor(model => model.requestResponse.CreateDate, "", new { @class = "text-danger" }) 
      </div> 
     </div> 



     <div class="form-group"> 
      <div class="col-md-offset-1"> 
       <button type="reset" class="btn btn-default">Cancel</button> 
       <input type="submit" value="Create" class="btn btn-success" /> 
      </div> 
     </div> 
    </div> 

    <hr /> 
    <h3 class="text-success">Original Request</h3> 
    <div class="row"> 
     <div class="col-md-10"> 
      <h4>@Html.DisplayFor(model => model.userRequest.Title)</h4> 
     </div> 
    </div> 

    <div class="row"> 
     <div class="col-md-10"> 
      <h4>@Html.DisplayFor(model => model.userRequest.Description)</h4> 
     </div> 
    </div> 

    } 

    <div> 
     @Html.ActionLink("Back to Browse", "Browse","Change") 
    </div> 

Erhalten Action:

public ActionResult Create(int id) 
    { 


     UserRequestContextDataContext db = new UserRequestContextDataContext(); 
     var request = (from m in db.Requests 
         where m.ID == id 
         select new Models.Request() 
         { 

          ID = m.ID, 
          Title = m.Title, 
          Description = m.Description, 
          BusinessUnit = m.BusinessUnit, 
          Author = m.Author, 
          ModuleName = m.MenuItem, 
          RequestStatus = 2, 
          SubmitDate = m.SubmitDate, 
          Type = m.Type, 
          UrgencyNum = m.UrgencyLevel 


         }).FirstOrDefault(); 

     var reqResponse = new Models.RequestResponse(); 


     var viewModel = new RequestResponseViewModel 
     { 
      userRequest = request, 
      requestResponse = reqResponse 

     }; 

     return View(viewModel); 
    } 

Das "viewModel" hier hat alles was ich brauche. Es ist irgendwo zwischen der ActionResults verloren ..

und schließlich der Beitrag Action:

[HttpPost] 
    public ActionResult Create(RequestResponseViewModel _requestResponseViewModel) 
    { 
     try 
     { 

      if (ModelState.IsValid) 
      { 
       using (UserRequestContextDataContext db = new UserRequestContextDataContext()) 
       { 

        RequestResponse reqRes = new RequestResponse(); 
        reqRes.Response = _requestResponseViewModel.requestResponse.Response.ToString(); 

        reqRes.RequestID = _requestResponseViewModel.userRequest.ID; 
        reqRes.Author = _requestResponseViewModel.requestResponse.Author.ToString(); 
        reqRes.CreateDate = DateTime.Now; 

        db.RequestResponses.InsertOnSubmit(reqRes); 
        db.SubmitChanges(); 
       } 
      } 

      return RedirectToAction("Browse","Change"); 
     } 
     catch (Exception ex) 
     { 

      return View("Error", new HandleErrorInfo(ex, "Change", "Create")); 
     } 
    } 

Debug-Modus Mit dem userRequest Objekt ist NULL in der Ansicht Modellparameter der POST-Methode aber Requestresponse ist FINE und bevölkert wie sollte.

auf diese Suche es schien die meisten hatten Probleme mit der Namenskonvention in der Modellansicht, aber ich habe dafür gesorgt, es gibt es keine Unstimmigkeiten.

Wenn es eine freiere Art und Weise ist es, diesen Workflow zu tun Bitte erwähnen ..

+0

Können Sie den Stack-Trace des Fehlers posten .. –

Antwort

1

@Html.DisplayFor nicht ein HTML-Eingabeelement erstellen, sondern eine einfache Stringliteral (für die meisten Arten sind einige Ausnahmen in der Dokumentation aufgeführt: https://msdn.microsoft.com/en-us/library/ee407420(v=vs.118).aspx#Anchor_1). Wenn Sie also auf "Senden" drücken, sendet Ihr Browser die ID nicht an den Server zurück, da nur Formulardaten gesendet werden (z. B. Daten von Eingabe, Textare, Auswahlfelder). Mit den Browser-Entwicklertools (F12) können Sie prüfen, was tatsächlich an den Server gesendet wird.

Sie können ein verstecktes Eingabefeld mit @Html.HiddenFor(model => model.userRequest.ID) oder eine benutzerdefinierten Anzeigevorlage für die ID hinzufügen verwenden, um automatisch ein verstecktes Eingabefeld hinzuzufügen. Sie können außerdem die Attribute UIHint verwenden, um automatisch eine Anzeigevorlage auszuwählen. Beide Ansätze sind gründlich dokumentiert (z. B. http://www.codeguru.com/csharp/.net/net_asp/mvc/using-display-templates-and-editor-templates-in-asp.net-mvc.htm).

+0

Große Antwort, klare Erklärung und Links Infos zu fördern. Hinzufügen der HiddenFor hat gut funktioniert. Ich habe bemerkt, dass ich hiddenFor() - Felder mit den GET-Methodenfeldern, die ich in meinem Controller abrufe, abgleichen muss oder dass mein Modellstatus nicht mehr gültig ist. –

Verwandte Themen