2011-01-15 66 views
0

私はマスターページでビューを持っています。ASP.Net MVC - モデルとユーザーコントロール

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<BudgieMoneySite.Models.SiteUserLoginModel>" %> 

このユーザーコントロールは、すべての画面(マスターページの一部)に表示されます。ユーザーがログインしている場合は、特定のテキストが表示され、ユーザーがログインしていない場合は、ログインボックスが表示されます。

これで問題なく動作します。

今、最初の機能画面を追加しています。だから私は新しいビューを作成しました...そして、コントローラメソッドを選択すると、基本的なビューコードが生成され、「ビューの作成」と呼ばれました。

 public ActionResult Transactions() 
    { 
     List<AccountTransactionDetails> trans = GetTransactions(); 
     return View(trans); 
    } 

    private List<AccountTransactionDetails> GetTransactions() 
    { 
     List<AccountTransactionDto> trans = Services.TransactionServices.GetTransactions(); 

     List<AccountTransactionDetails> reply = new List<AccountTransactionDetails>(); 

     foreach(var t in trans) 
     { 
      AccountTransactionDetails a = new AccountTransactionDetails(); 
      foreach (var line in a.Transactions) 
      { 
       AccountTransactionLine l = new AccountTransactionLine(); 
       l.Amount = line.Amount; 
       l.SubCategory = line.SubCategory; 
       l.SubCategoryId = line.SubCategoryId; 
       a.Transactions.Add(l); 
      } 
      reply.Add(a); 
     } 


     return reply; 
    } 

はそう、私の見解はこれで生成されました:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<System.Collections.Generic.List<BudgieMoneySite.Models.AccountTransactionDetails>>" %> 

見つかり<% = Model.Count()%>取引

私のコントローラは、このコードを持っています。

私が今表示したいのは、表示するレコードの数だけです。

私はそれを実行すると、私はエラーを取得:

「辞書に渡されるモデルアイテムはタイプ 『System.Collections.Generic.List`1 [BudgieMoneySite.Models.AccountTransactionDetails]』であるが、これ辞書には、 'BudgieMoneySite.Models.SiteUserLoginModel'タイプのモデルアイテムが必要です。

ユーザーコントロールが最初にレンダリングされているように見えます。コントローラーのモデルがマイリスト<>のように表示されています。

私は間違っていますか?

答えて

1

LoginModelをページのモデルとして設定するのではなく、部分的なビューのみを設定します。 RenderActionを使用して、ページのモデルに接続されていないモデルの部分ビューを表示できます。マスターページに表示されるログインステータスコントロールを実装した方法は次のとおりです。

部分ビュー(ビュー/認証/ LoginStatus.ascx):

<% Html.RenderAction("LoginStatus", "Auth"); %> 

とコントローラで(:強く型付けされたモデルを持っていないマスターページでは、

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IUserProfile>" %> 

<% if (Request.IsAuthenticated && Model != null) { %> 
    Welcome <b><%= Model.DisplayName %></b>! 
    [ <%= Html.ActionLink("Log Off", "LogOff", "Auth") %> ] 
<% 
} 
else { 
%> 
    [ <%= Html.ActionLink("Log On", "Login", "Auth") %> ] 
<% 
} 
%> 

public ActionResult LoginStatus() 
    { 
     TProfile p = null; 
     if (User.Identity.IsAuthenticated) 
     { 
      p = Data.Profiles.Get(ulong.Parse(User.Identity.Name)); 
     } 
     return View(p); 
    } 
+0

ありがとうTom!それは何とか働いた。どのように考えているのかわからないので、今分析しようと思っています...しかし、ありがとう! – Craig

1

それが「最初の」それ自体でレンダリングされているわけではありません。特に明記しない限り、すべてのビューはコントローラーが引き継ぐモデルになります。

これを解決するには、すべてのビューモデルが継承する基本クラスを作成し、マスターとその部分ビューに必要なものを定義します(そして、適切なプロパティをRenderPartialオーバーロードの1つに渡します) )、または型なしのViewDataバッグを使用して同様のことを行うことができます。

* EDIT * 尋ねたとして、だから、私はそれを解決しているだろうではないとして、私はあなたの質問に答えたことに気づきました。上記のレスポンスは真です。マスターページのモデルを扱うには、ViewData辞書に入れておく必要があります(例:ViewData ["myData"] = mydata;)モデルを継承する。

しかし、ほとんどの場合(例としてprofielのようなものがあります)、私はどちらもしません。このようなほとんどの場合、代わりにレンダリング・アクションを使用します。これは、別のコントローラからの部分的なビューを必要とします。その場合、他のコントローラは、データが適切であればその部分を供給することができる。 MVCに違反していると思う人もいますが、何もしていなくてもマスタページに必要なものをコントローラに要求することで、ビューを作成して論理構造を損なわないようにするのは良い方法です/そのコントローラの仕事。それに対する通常の解決策は、ベースコントローラーを使用するか、アクションフィルターを使用することですが、維持しなければならないほど膨らんでいることがわかります。

+0

ありがとうポール - これの初心者として、私は行くのが良い方法は分かりません。また、非常に基本的な例を手助けできますか?モデルをビューに渡すつもりですか? – Craig

+0

異なる人々は、異なる好みを持っています。実際、MVC 3では、周囲を回る方法としてダイナミクスを使用することさえできます。初心者の方は、SandressによってMVressの本を読んでみてください。最高です。私は上記のいくつかの他のアイデアを編集します – Paul

関連する問題