2016-08-24 7 views
0

コントローラは、ビューを通過するとき、私は次のエラーを取得しています:ASP.NET MVCビューリスト<MyViewModel>エラー

エラー

'List<GrantsViewModel>' does not contain a definition for 'StateName' and no extension method 'StateName' accepting a first argument of type 'List<GrantsViewModel>' could be found (are you missing a using directive or an assembly reference?) 

モデル

public class StateName 
    { 
     [Key] 
     public int StateId { get; set; } 
     public string State { get; set; } 
     public string StateNumber { get; set; } 
    } 

public class AnnualGrant 
    { 
     [Key] 
     public int GrantNo_Id { get; set; } 
     public string StateNumber { get; set; } 
     public int FiscalYear { get; set; } 
     public string GrantNo { get; set; } 
    } 

public class MyProjectContext : DbContext 
    { 
     public MyProjectContext (DbContextOptions<MyProjectContext> options) : base(options) 
     { } 
     public DbSet<StateName> StateNames { get; set; } 
     public DbSet<AnnualGrant> AnnualGrants { get; set; } 
    } 

のViewModel

public class GrantsViewModel 
    { 
     public int GrantNo_Id { get; set; } 
     public string StateNumber { get; set; } 
     public string StateName { get; set; } 
     public string GrantNo { get; set; } 
     public int FiscalYear { get; set; } 
    } 

コントローラー

public class DbTestController : Controller 
    { 
     private MyProjContext _context; 

     public DbTestController(MyProjContext context) 
     { 
      _context = context; 
     } 

    public IActionResult GrantNumbers() 
    { 
     var qryVM = from s in _context.StateNames 
       join g in _context.AnnualGrants on s.StateNumber equals g.StateNumber into sg 
       from r in sg.DefaultIfEmpty() 
      select new GrantsViewModel() { StateNumber = s.StateNumber,StateName= s.State, GrantNo= (r == null ? String.Empty : r.GrantNo), FiscalYear = (r == null ? 1900 : r.FiscalYear) }; 

     return View(qryVM.ToList()); 
    } 
} 

ビュー:注:

@model List<MyProjet.Models.GrantsViewModel> 

<form asp-controller="DbTest" asp-action="GrantNumbers" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post"> 
      <table class="table"> 
       <thead> 
        <tr> 
         <th> 
          @Html.DisplayNameFor(model => model.StateName) 
         </th> 
         <th> 
          @Html.DisplayNameFor(model => model.GrantNo) 
         </th> 
         <th></th> 
        </tr> 
       </thead> 
       <tbody> 
        @foreach (var item in Model) 
      { 
         <tr> 
          <td> 
           <input asp-for="StateName" /> 
          </td> 
          <td> 
           @Html.DisplayFor(modelItem => item.GrantNo) 
          </td> 
          <td></td> 
         </tr> 
        } 
       </tbody> 
      </table> 
      <button type="submit" class="btn btn-default">Save</button> 
     </form> 

答えて

2

モデルは何StateNameを持っていないList<>、次のとおりです。エラーは、このビューで発生しプロパティ。リスト内の要素のそのプロパティが必要です。このような何か:

@Html.DisplayNameFor(model => model.First().StateName) 

実際に(リストが空の場合、この場合にはエラーを投げることができた)リストから要素を引っ張っているようにそれは感じているので、それは少し奇妙に思えるかもしれません。しかし、フレームワークは実際にはリスト自体にドリルダウンしません。フレームワークは実際にはインスタンスを反復するのではなく、型を反映するようにしています。そして、これは単に見ている型システムのどこにそれを伝えています。

+1

そして@ Html.DisplayNameFor(モデルであれば、それはあなたのビューが強くIEnumerable<T>に型付けされている場合にのみ、それは動作しません動作します覚えておいてください変更=> model.First()。GrantNo):) –

+0

モデルリストが空であれば例外をスローすることはありませんか? – serhiyb

+1

@serhiyb:直観的にはそういう感じですが、フレームワークは実際にはクエリを実行しません。これはコレクションに反復するのではなく、型に反映するためのものです。 – David

1

デビッドの答えはあなたの問題を解決する必要があります。ここに別の解決策があります。

あなたのビューが強くIEnumerable<T>に入力された場合、それが動作IEnumerable<T>

public static MvcHtmlString DisplayNameFor<TModel, TValue>(
    this HtmlHelper<IEnumerable<TModel>> html, 
    Expression<Func<TModel, TValue>> expression 
) 

で動作します。この方法の別のオーバーロードがあります。

だからあなた@model List<MyProjet.Models.GrantsViewModel>

@model IEnumerable<MyProjet.Models.GrantsViewModel> 
<table class="table"> 
    <thead> 
     <tr> 
      <th> 
       @Html.DisplayNameFor(g=>g.StateName) 
      </th> 

     </tr> 
    </thead> 
    <tbody> 
    @foreach (var item in Model) 
    { 
     <tr> 
      <td><input asp-for="StateName" /></td>    
     </tr> 
    } 
    </tbody> 
</table> 

はそれがList<T>IList<T>

+0

ソリューションを共有していただきありがとうございます。私のプロジェクトでどこにメソッドのオーバーロードを追加する必要がありますか? – nam

+0

何も追加する必要はありません。あなたは単純にそれを使います( '@Html.DisplayNameFor(g => g.StateName))'。答えをお読みください。 – Shyju

+0

あなたが示唆したものにコードを変更した後も、 ' 'に' StateName '。さらに、Intellisenseは '@Html.DisplayNameFor(g => g.StateName)'でStateNameを認識しません。しかし、 'g.StateName'をハードコードするとエラーは表示されません。 ' – nam

関連する問題