web-dev-qa-db-ja.com

Razor宣言ビューからのMVC HtmlHelper拡張機能の使用

MVC 3 RTMプロジェクトのApp_CodeフォルダーにRazor宣言型ヘルパーを作成しようとしていました。

私が遭遇した問題は、ActionLinkなどのMVC HtmlHelper拡張機能が利用できないことです。これは、コンパイルされたヘルパーがSystem.Web.WebPages.HelperPageから派生し、Htmlプロパティを公開しているが、そのタイプはSystem.Web.WebPages.HtmlHelperではなくSystem.Web.Mvc.HtmlHelperであるためです。

私が得ていた種類のエラーの例は次のとおりです。

「System.Web.Mvc.HtmlHelper」には「ActionLink」の定義が含まれておらず、「System.Web.Mvc.HtmlHelper」タイプの最初の引数を受け入れる拡張メソッド「ActionLink」が見つかりませんでした(usingディレクティブがありませんか?またはアセンブリ参照?)

私の唯一の解決策は、独自のHelperPageを作成し、Htmlプロパティをオーバーライドすることです。

using System.Web.WebPages;

public class HelperPage : System.Web.WebPages.HelperPage 
{
    // Workaround - exposes the MVC HtmlHelper instead of the normal helper
    public static new HtmlHelper Html
    {
        get { return ((System.Web.Mvc.WebViewPage) WebPageContext.Current.Page).Html; }
    }
}

それから、すべてのヘルパーの先頭に次を書く必要があります。

@inherits FunnelWeb.Web.App_Code.HelperPage
@using System.Web.Mvc
@using System.Web.Mvc.Html

@helper DoSomething()
{
    @Html.ActionLink("Index", "Home")
}

MVC 3でこれを難しくするつもりですか、それとも何か間違ったことをしていますか?

122
Paul Stovell

この質問に対する Marcind 's answer をご覧ください。あなたが経験しているのは、App_Codeフォルダーに宣言的なビューを置くことの制限です。

ヘルパーをApp_Codeに配置することはできますが、特定のMVCシナリオに影響する特定の制限があります(たとえば、標準のMVC Htmlヘルパーにアクセスできません)。

42
Omar

ページヘルパーにアクセスできるように、WebPagesヘルパーの拡張メソッドを作成しました。

public static HtmlHelper GetPageHelper(this System.Web.WebPages.Html.HtmlHelper html)
{
 return ((System.Web.Mvc.WebViewPage) WebPageContext.Current.Page).Html;
}
38
Jake Hoffner

Omarには正しい答えがありますが、何かを追加したかったのです(Omarの回答を回答としてマークしてください)。

V1ではこれを認識しており、製品に大きな修正を加えることはできませんでしたが、David Ebbo(ASP.Netチームのアーキテクト)は、基本的に最初の調査であるVisual Studio Code Generatorのサンプルを投稿しましたこの機能を適切に機能させるために考えているアイデア: http://blogs.msdn.com/b/davidebb/archive/2010/10/27/turn-your-razor-helpers-into -reusable-libraries.aspx

それを試して、あなたの考えを見てください!ブログに投稿して、コメントがあるかどうかデビッドに知らせてください。

11

@Jakes回答に似ています:

public static class MvcIntrinsics {
    public static System.Web.Mvc.HtmlHelper Html {
        get { return ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Html; }
    }

    public static System.Web.Mvc.AjaxHelper Ajax {
        get { return ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Ajax; }
    }

    public static System.Web.Mvc.UrlHelper Url {
        get { return ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Url; }
    }

}

使用法:

@MvcIntrinsics.Html.Raw("test")

ソース:Dino Esposito-プログラミングMicrosoft ASP.NET MVC

9
Greg Gum

代替ソリューション:

あなたのrazor-helperファイルの上にこれを追加してください:

@functions {
    public static System.Web.Mvc.HtmlHelper<object> HHtml = ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Html;
}

次のように呼び出します:

@HHtml.ActionLink("actionname")
7
Alex

検索者の利益のために、MVCビューをクラスライブラリの一部として作成するときに同じエラーが発生しました(コンポーネントの再利用のため)。上記で部分的に示唆された解決策は、.cshtmlファイルの先頭に次のusingステートメントを追加することでした。

@using System.Web.Mvc
@using System.Web.Mvc.Html

これ以上の作業は必要ありません。

4
HockeyJ

これへの私のアプローチは、ページをヘルパーメソッドへのパラメーターとして単に渡すことです。したがって、あなたの例では:

@helper DoSomething(WebViewPage page)
{
    @page.Html.ActionLink("Index", "Home")
}

次に、Razorビューで必要な場所で次のように呼び出します。

@YourHelperFilename.DoSomething(this)

これをすぐに行うと、通常持っているHtmlUrlなどのページプロパティにアクセスできます(これにより、HtmlHelper拡張機能)。

追加の利点として(必要な場合)、ページのViewDataなどのインスタンスプロパティにもアクセスできます。

3
Dejan

ASP.NET MVCがVS 2013でこの問題を修正したようです。この投稿を参照してください http://aspnet.uservoice.com/forums/41201-asp-net-mvc/suggestions/3670180-support-helper- extensionmethod-this-htmlhelper-ht

0
Omar

MVC 3にはいくつかのインテリセンスの問題があることを知っています。web.configで名前空間を設定していれば、ヘルパーは引き続き機能すると思います。

MVC 3 RTMは、これまたはベータ版を使用していますか?

0
Lee Smith