2009-06-05 14 views
0

C#、.NET 3.5、およびMVCの新機能を少し理解しています。"GET"作成アクション中にドロップダウンリストに値を入力しようとするとエラーが発生する

私はMVC NerdDinner例を通じて実行しているとあなたがここのViewModelを見れば:http://nerddinnerbook.s3.amazonaws.com/Part6.htm#highlighter_662935

あなたは国のリストとどのようにそれが読み込まれますを見ることができ、これは正常に動作するようですが、私は同様の操作を行うことを試みましたLINQを使用して以下のものがあり、IEnumerableインターフェイスを継承していても、SelectListアプローチで問題が発生しています。

ステータステーブルへの外部キーを持つタスクテーブルがあります。以下のコードは、作成アクションでGETを実行すると、NullReferenceExceptionを返します。私は、匿名のタスクオブジェクトにはステータスが設定されていないことがわかります。だから、おそらくそれをチェックする必要がありますが、NerdDinnerの例ではこれがどのように行われていないのか分かりません。

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

私はタイプのドロップダウンメニューと作品ドロップダウンの人口のためにLINQを使用して、別のアプローチをしましたが、私はポストが行われ、詳細ビューが返されたら、それは正しい値を選択したかどうかをテストするために、まだです。私はまた、私のレポジトリにこの種のことをやっているクラスを持っているのではなく、これがどうやって私のリポジトリに移されるべきかどうか疑問に思っていますか?ここで

はコードです:

//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> 

とTaskFormビューには、タスクのコンストラクタには何がSystem.Web.Mvc.ViewUserControl

答えて

0

これをよりよく理解しようとする私の試み。

//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; 
     } 

私はSelectListのはMultiSelectListの基本クラスを使用し、そのコンストラクタがここにあることがわかります。

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

私はこのプロジェクトは、HTMLは次のように与えられている実行する場合:

<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> 

期待される。

私は、コントローラのコードを変更した場合:

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

それから私はとNullReferenceExceptionを取得します。これはArgumentNullExceptionではないので、例外のルートは最初のSelectList引数ではないようです。私が理解しようとしているのは、これがどうして起こるかです。 コントローラの作成アクションでTask.StatusをTaskに追加する必要があるためですか?

私は上記の作業に使用したLINQアプローチを使用するようにこのコードを変更します。これから達成しようとしていることは、何が起こっているのかを理解することです。

+0

問題を解決できましたか?はいの場合、どうですか? –

0

を継承しますか?新しく作成されたタスクの.typeIdの値は何ですか?それはヌル参照ですか?

作成ビューに送信されるビューモデルでは、タスクコンストラクタ(または他の初期化コード)がこれらのプロパティのデフォルト値を設定しない限り、選択したリスト項目を設定しないでください。 task.typeIdがnullの場合、選択リストを作成するコードにエラーが発生します。

0

私は、新しく作成されたタスクに値を追加しないと、タイプまたはステータスにNULL値を取得することを理解します。私が理解していないこと、および私が明らかにしなかったことは以下の通りです。 ビューモデルにCountriesプロパティがあり、選択された値がDinner.Countryに設定されていることがわかります.Dinner.Countryは作成アクションに設定されていません。どうしてこれがnull例外を与えないのでしょうか?

//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> 
関連する問題