2009-06-05 15 views
0

Ich versuche etwas besser zu verstehen, da ich neu in C#, .NET 3.5 und MVC bin.Fehler beim Auffüllen einer Dropdown-Liste während einer "GET" -Erstellungsaktion

ich durch das MVC NerdDinner Beispiel leite und wenn man sich das Ansichtsmodell hier: http://nerddinnerbook.s3.amazonaws.com/Part6.htm#highlighter_662935

Sie können die Länderliste sehen und wie es bevölkert wird, das scheint gut zu funktionieren, aber ich versuchte ein ähnliches zu tun sache unter Verwendung von LINQ und ich habe Probleme, mit dem SelectList-Ansatz, obwohl er von der IEnumerable-Schnittstelle erbt.

Ich habe eine Aufgabentabelle mit einem Fremdschlüssel zu einer Statustabelle. Der folgende Code gibt mir eine NullReferenceException, wenn ich einen GET für eine Erstellungsaktion ausführen. Ich kann sehen, dass ein anonymes Aufgabenobjekt keinen Status hat. Also muss ich wahrscheinlich nachsehen, aber ich verstehe nicht, wie das für das NerdDinner Beispiel nicht gemacht wird ??

 public class TaskViewModel { 
     // Properties 

     public Task Task { get; private set; } 
     public SelectList Status { get; private set; } 

     // Constructor 
     public TaskViewModel(Task task) { 
      TaskRepository taskRepo = new TaskRepository(); 
      Task = task; 
      Status = new SelectList(taskRepo.GetStatus(), Task.Status.description); 
     } 

    } 

     // 
     // GET: /Tasks/Create 

     public ActionResult Create() 
     { 
      Task task = new Task(); 

      return View(new TaskViewModel(task)); 
     } 


//Code from TaskRepository 

     private TaskManagerDataContext db = new TaskManagerDataContext(); 

     public IQueryable<Status> GetStatus() { 
      return from status in db.Status 
        orderby status.description 
        select status; 
     } 

habe ich einen anderen Ansatz LINQ für die Drop-Down-Typ und der Bevölkerung der Drop-down funktioniert, aber ich bin noch zu testen, ob es den richtigen Wert wählt einmal ein Post gemacht wird und die Details anzuzeigen, die zurückgegeben wird. Ich frage mich auch, ob dies etwas in mein Repository verschoben werden sollte, anstatt eine Klasse in meinem Controller zu haben, die so etwas macht ??

Hier ist der Code:

//In TaskViewModel Class 
     public IEnumerable<SelectListItem> Types { get; private set; } 

//In TaskViewModel constructor 

       IList<NPType> types = taskRepo.GetTypes().ToList(); 

      Types = 
       from type in types 
       select new SelectListItem { 
        Selected = (type.typeId == task.typeId), 
        Text = type.description, 
        Value = type.typeId.ToString() 
       }; 

//The TaskForm partial View that is used for the Create action of the TaskController 
      <p> 
       <label for="type">type:</label> 
       <%= Html.DropDownList("Type", Model.Types)%> 
       <%= Html.ValidationMessage("type", "*") %> 
      </p> 
      <p> 
       <label for="status">status:</label> 
       <%= Html.DropDownList("Status", Model.Status)%> 
       <%= Html.ValidationMessage("status", "*") %> 
      </p> 

und die TaskForm Ansicht erbt System.Web.Mvc.ViewUserControl

Antwort

0

Mein Versuch zu versuchen, dies besser zu verstehen.

//controller code creating a select list in the viewmodel class. 
//taskRepo.GetStatus() returns an IQueryable<Status> 
     Status = new SelectList(taskRepo.GetStatus(), Task.Status); 

//MVC Framework SelectList class constructor and ToEnumerable method 
      public SelectList(IEnumerable items, string dataValueField, string dataTextField, object selectedValue) 
      : base(items, dataValueField, dataTextField, ToEnumerable(selectedValue)) { 
      SelectedValue = selectedValue; 
     } 

     private static IEnumerable ToEnumerable(object selectedValue) { 
      return (selectedValue != null) ? new object[] { selectedValue } : null; 
     } 

ich, dass Select sehen verwendet, um seine Basisklasse von MultiSelectList und Konstruktor ist hier:

 public MultiSelectList(IEnumerable items, string dataValueField, string dataTextField, IEnumerable selectedValues) { 
     if (items == null) { 
      throw new ArgumentNullException("items"); 
     } 

     Items = items; 
     DataValueField = dataValueField; 
     DataTextField = dataTextField; 
     SelectedValues = selectedValues; 
    } 

Als ich dieses Projekt laufen die html ist gegeben als:

<select id="Status" name="Status"><option>NPTaskManager.Models.Status</option> 
<option>NPTaskManager.Models.Status</option> 
<option>NPTaskManager.Models.Status</option> 
<option>NPTaskManager.Models.Status</option> 
</select> 

Welche ist zu erwarten.

Wenn ich den Controller-Code zu ändern:

Status = new SelectList(taskRepo.GetStatus(), Task.Status.statusId.ToString(), Task.Status.description); 

Dann bekomme ich eine Nullreferenceexception.Da dies keine ArgumentNullException ist Es scheint mir, dass der Stamm der Ausnahme nicht das erste SelectList-Argument ist. Was ich versuche zu verstehen ist, wie all das geschieht? Liegt das daran, dass Task.Status in der Erstellungsaktion des Controllers zum Task hinzugefügt werden muss?

Ich werde diesen Code ändern, um den LINQ-Ansatz zu verwenden, den ich für die obige Aufgabe verwendet habe. Alles, was ich jetzt zu erreichen versuche, ist ein gewisses Verständnis dessen, was vor sich geht.

+0

konnten Sie dieses Problem lösen? wenn ja, wie? –

0

Was in der Task-Konstruktor ist? Was ist der Wert von .typeId für eine neu erstellte Aufgabe? Ist es eine Nullreferenz?

Für das Ansichtsmodell, das an Ihre Create-Ansicht gesendet wird, sollten Sie nicht versuchen, das ausgewählte Listenelement festzulegen, es sei denn, Ihr Taskkonstruktor (oder anderer Initialisierungscode) legt Standardwerte für diese Eigenschaften fest. Wenn task.typeId null ist, wird der Code, der die Auswahlliste erstellt, einen Fehler erhalten.

0

Ich verstehe, dass ich einen Nullwert für den Typ oder den Status erhalten werde, wenn ich der neu erstellten Aufgabe keinen Wert hinzufügen. Was ich nicht verstehe und was ich nicht klar habe, ist das Folgende. Sie können sehen, dass das Ansichtsmodell über eine Ländereigenschaft verfügt und der ausgewählte Wert auf "Dinner.Country" festgelegt ist. Jetzt wird "Dinner.Country" nicht in der Erstellungsaktion festgelegt. Wie kommt es also zu einer Null-Ausnahme?

//viewmodel code 
      public DinnerFormViewModel(Dinner dinner) { 
      Dinner = dinner; 
      Countries = new SelectList(PhoneValidator.Countries, Dinner.Country); 
     } 

//controller code 
     public ActionResult Create() { 

      Dinner dinner = new Dinner() { 
       EventDate = DateTime.Now.AddDays(7) 
      }; 

      return View(new DinnerFormViewModel(dinner)); 
     } 

//view code 
      <p> 
      <label for="Country">Country:</label> 
      <%= Html.DropDownList("Country", Model.Countries) %>     
      <%= Html.ValidationMessage("Country", "*") %> 
     </p> 
Verwandte Themen