web-dev-qa-db-ja.com

ASP.NET MVCRazorを使用したカスタムコントロール

ASPNET.MVC Razorでカスタムコントロールを使用するにはどうすればよいですか?

Razorビューでカスタムコントロールを使用したい。例えば:

<mycontrols:something>@Model.MyVar</mycontrols:something>

または

<mycontrols:something myattribute="@Model.MyVar" />

私の目標は、MvcControlから派生した少数のコントロールのみを使用することであり、些細な繰り返しのuiのものにのみ使用することに注意してください。

ビューの上部に書き込む@Registerに似た構文を見つけようとしましたが、成功しませんでした。

次に、web.configに移動して、追加しました

<pages>
   <controls>
      <add tagPrefix="mycontrols" namespace="mynamespace" Assembly="myassembly"/>
   </controls>
</pages>

しかし、カスタムコントロールはレンダリングで無視されているようです。

誰かが助けることができますか?

...少し古い方法かもしれませんが、コードをよりクリーンにするためにカスタムコントロールが役立つ場合もあります。

19
Fabrizio

Razor構文は、コントロールの概念をまったくサポートしていません。コントロールを使用する場合は、ASPX(WebForms)構文を使用する必要があります。

ただし、推奨されるMVCパターンは、htmlヘルパー関数または部分ビューを使用することです。 Razorでは、クイックヘルパー関数に@helper構文を使用することもできます。

19
marcind

ASP.NET MVCでは、カスタムサーバーコントロールは避ける必要があります。それらのほとんどは、MVCに存在しなくなった概念であるViewStateとPostBackに依存しています。テンプレートやHTMLヘルパーを使用して、再利用可能な機能を実装することをお勧めします。コントロールに関する別の問題は、それらのほとんどが、どこかからデータをフェッチし、それをアンチMVCパターンでレンダリングするビジネスロジックをカプセル化することです。 MVCでは、モデルを操作してデータをフェッチし、ビューモデルをビューに渡すのはコントローラーの責任です。ビューモデルは単にそれを表示する必要があります。

10
Darin Dimitrov

MVCは、カスタムコントロールではなく部分ビューを使用し、カスタムコントロールで実行できるほとんどすべてをカバーする2つの方法で使用できます。

  • ページコントローラーによって既に取得されたデータをレンダリングするRenderPartial
  • 同様ですが、独自のコントローラーアクションがあるため、データを個別に取得できるRenderAction

Mvcビューにカスタムコントロールを配置する価値があると私が考えることができる唯一のシナリオは、部分的に移行されたWebフォームプロジェクトで作業している場合であり、それがWebFormsViewEngine以外で機能するとは思えません。

6
Tom Clarkson

私は判断するためにここにいるわけではありませんが、私はそれをお勧めしませんが、あなたはこれを行うことができます。ポストバックとビューステートも機能し続けるとは思わないが、少なくともすべてのhtmlをレンダリングできると付け加えるかもしれません。

かみそりはウェブフォームのビューエンジンコントロールをサポートしていないため、これを行う唯一の方法はちょっとしたハックです。ただし、webformsビューエンジンで作成された部分ビューはサポートします。したがって、ハッキーな解決策は、コントロールを含む部分的なビューをそのように含めることです。

たとえば、mvc3プロジェクトでoffice web uiリボンを使用したい場合は、次のように含めることができます。

<body>
    <div>
        @Html.Partial("_RibbonPartial")
    </div>
</body>

あなたの見解では。 _Ribbonのタイプは.aspxです。

次に、部分ビューで、コントロールを使用してrunat = "server"を設定し、runat = "server"を使用してフォーム内に配置します。

//_Ribbon.aspx
<form id="form1" runat="server">
    <XyzControls:Manager ID="Manager1" runat="server" UITheme="Silver" />
    <XyzControls:OfficeRibbon ID="OfficeRibbon1" runat="server" ApplicationMenuColor="#267c29"
        ApplicationMenuText="Item" ApplicationMenuType="Backstage">
//... rest of control code
</form>

次に、ポストバックを使用する代わりに、ajaxを使用してイベントを実装する必要があります。

次に、クリーンアップするために、不要なポストバック用のWebフォームビューエンジンから生成されたコードを削除します。それを保持してみることができますが、私はそうしていません。どうなるかわかりません。本当に厄介なハッキーなものに取り掛かりたい場合は、偽のビューステートを作成する方法もあることを知っていますが、Webフォームから余分なコードを削除するには、次のjqueryを使用できます。

$(function ()
{
    // we don't need any of the webforms stuff
    $("#__EVENTTARGET","#aspnetForm").parents("div:first").remove();
    $("#__EVENTVALIDATION","#aspnetForm").parents("div:first").remove();
});
1

私も同じ要求がありました。 Razor/MVCページからカスタムWebコントロールを使用したかった。ポストバックを処理するコントロールでそれを行うべきではありません。それをサポートするイベントサイクルはありませんが、「レンダリングコントロール」を使用することが唯一の要求である場合は、それをかみそりでインスタンス化し、レンダリングが行われる場所を制御できます。

@{
  var myControl = new mycontrols.something();
  myControl.myattribute = Model.MyVar;
  mycontrol.RenderControl(new HtmlTextWriter(this.Output));
}
1
Jesper Jensen