2016-12-05 7 views
0

Neuling hier. Ich erhalte den Fehler The resource cannot be found. beim Anfordern der URL /Ereignis/Details/3. Ich benutze einen MVVM.ASP.Net MVC5 - "Ressource kann nicht gefunden werden" Fehler

Mein Schema ist einfach. Ich habe "Event", "Person" und "PersonInEvent" -Tabellen. "PersonInEvent" ist eine Junction-Tabelle für die beiden anderen (enthält die Fremdschlüssel).

Ich versuche, in der Ansicht "Details" die Daten des Ereignisses mit seiner ID anzuzeigen (/event/details/3). Die ID des Ereignisses wird an die Controlleraktion "Details" übergeben, die mein ViewModel, das ein Ereignisobjekt enthält, instanziiert. Ich setze dieses Ereignis als das mit der ID, die ich erhalte, wenn das Viewmodel erstellt wird.

Nach meinem Controller (siehe unten) bekomme ich den Fehler, weil vm.Event == null. Aber ich kann keinen Weg finden, dieses Problem zu lösen. Ich habe das Gefühl, dass es sich um ein grundlegendes Programmierproblem handelt, etwa wie meine "Event" -Eigenschaft in meinem Viewmodel erstellt wird. Aber ich kann immer noch keine Lösung finden. Danke im Voraus.

Einzelheiten Mein Controller Aktion:

[HttpPost] // this was the problem 
[ValidateAntiForgeryToken] 
public ActionResult Details(int id) 
    { 
     var vm = new EventDetailsViewModel(id); 

     if (vm.Event == null) 
     { 
      return HttpNotFound(); // I get the error because of this imo 
     } 

     return View("Details", vm); 
    } 

Meine Ansicht Modell:

public class EventDetailsViewModel 
    { 
     private readonly ApplicationDbContext _db = new ApplicationDbContext(); 

     private readonly int _eventIdVm; 
     private Event _event; 

     public EventDetailsViewModel(int id) 
     { 
      _eventIdVm = id; 
      _event.EventId = id; 
     } 

     public Event Event 
     { 
      get 
      { 
       return _event = _db.Event.Find(_eventIdVm); 
      } 

      set { _event = value; } 
     } 

     public List<Person> Persons 
     { 
      get 
      { 
       if (!_db.PersonInEvent.Any(pe => pe.EventId == _eventIdVm)) 
       { 
        return Enumerable.Empty<Person>().ToList(); 
       } 
       var personsOfEvent = _db.PersonInEvent.Where(pe => pe.EventId == _eventIdVm) 
        .Select(pe => pe.Person) 
        .ToList(); 
       return personsOfEvent; 
      } 
     } 
    } 

Meine Ansicht für alle Fälle:

@model BillSplittingWebApp.ViewModels.EventDetailsViewModel 

@{ 
    ViewBag.Title = "Details"; 
} 

<h2>Details</h2> 

<div> 
    <h4>Event</h4> 
    <hr /> 
    <dl class="dl-horizontal"> 
     <dt> 
      @Html.DisplayNameFor(model => model.Event.EventName) 
     </dt> 

     <dd> 
      @Html.DisplayFor(model => model.Event.EventName) 
     </dd> 

     <dt> 
      @Html.DisplayNameFor(model => model.Event.EvenTimeBegin) 
     </dt> 

     <dd> 
      @Html.DisplayFor(model => model.Event.EvenTimeBegin) 
     </dd> 

    </dl> 
</div> 

EDIT: Problem war das Attribut [HttpPost] dass Ich habe vergessen, für die Acti zu entfernen auf.

+2

Die 'Details' oben beschriebene Methode nur wird aufgerufen, wenn ein Formular gebucht wird, wegen des Attributs [Httppost] . Haben Sie auch eine 'Details' Methode, die das Attribut [HttpGet] verwendet? Wenn ja, bitte fügen Sie diesen Code auch in Ihre Frage ein. –

+0

@Peter B Das war es wirklich ... Ich habe versucht, die ID früher per Post-Methode zu senden, und ich habe vergessen, die Attribute zu entfernen. –

+1

Randnotiz, das ist nicht MVVM, es ist MVC. Deshalb heißt es aspnet * MVC *. – Will

Antwort

3

Dies ist ein schlechter Weg MVC ist ein Muster, das es selbst ist. ViewModels sollte nicht direkt auf Datenbanken verweisen. Das Problem ist jedoch, dass Sie in Ihrem ViewModel ein privates Event-Objekt deklariert haben. Im Konstruktor versuchen Sie, die ID dieses Objekts zu setzen, ohne zuerst eine neue Instanz zu installieren.

Sie diese Codezeile entfernen, da es nicht etwas Nützliches im Konstruktor sowieso tun hat:

_event.EventId = id; 
+0

Danke Bilpor. Problem war mein _HttpPost_ Attribut, wie Peter im Kommentar sagte. Die Zeile, die du erwähntest, warf auch einen Fehler auf, der verschwand, sobald ich ihn entfernte. "_ViewModels sollte nicht direkt auf Datenbanken verweisen", also sollte ich die Eigenschaften des Ansichtsmodells in meinem Controller auffüllen und die Logik in diesem Controller erstellen. Ist das das, was du meinst? –

+1

Ja, der Punkt von MVC ist in seinem Namen Model-View-Controller. Controller sollten so leicht wie möglich sein, und die beste Möglichkeit, diese zu betrachten, sind Vermittlungsmechanismen, um Daten an eine Service-Schicht und eine Datenschicht weiterzuleiten. Die viewModels sollten die Daten definieren, die die Ansicht anzeigen muss. Es ist in Ordnung, Konstruktoren hier zu haben, aber sie werden vom Controller zugewiesen. (Suche nach Trennung), SOLID Principles und DRY. Entscheide immer mit diesen Gedanken und du wirst nicht viel falsch machen. Beachten Sie auch "defensive" Codierung. Wenn es gebrochen werden kann, wird es jemand brechen. – bilpor

Verwandte Themen