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


121

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でこれが難しいことを意味しているのですか、それとも何か間違っているのですか?


4
Urlヘルパーも必要な場合は、次のコード行をHelperPageに追加します。public static UrlHelper Url {get {return new UrlHelper(Html.ViewContext.RequestContext); }}
Marco Staffoli

回答:


42

見てくださいMarcindの答えこの質問への。発生しているのは、App_Codeフォルダに宣言型ビューを配置することの制限です。

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


1
他の読者への注意:この答えは完全に正しいですが、潜在的な回避策については、以下のAndrew Nurseの追加の貢献も確認してください。
ジョーダングレイ

38

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

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

4
使用法:@Html.GetPageHelper().ActionLink("actioname")
deerchao

これは私にとっては機能しますが、App_Code内のcshtmlヘルパーファイルに追加@using System.Web.Mvcしなければなりません@using System.Web.Mvc.Htmlでした
Tomino

1
なぜ別のHtmlHelperクラスがあるのですか?App_Codeでもビューでも同じでなければなりません。壮大な半分実装されたデザインは失敗します。
Triynko

weblogs.asp.net/scottgu/…からここで参照されました。これは、「グローバル」なRazorヘルパーの作成方法を説明する良い仕事をします。あなただけの必要がある場合に、その後、HtmlHelper目的をエンコードするためのクラスを、私は静的クラス経由でこれを行うにしても迅速な方法を見つけたMicrosoft.Security.Application.Encoder:のようにEncoder.HtmlAttributeEncode(value)
マット・ボルハ

11

ここでオマーの答えは正しいですが、私は何かを追加したかったのです(オマーの応答を答えとしてマークしてください)。

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

それを試して、あなたの考えを見てください!ブログに投稿して、コメントがある場合はDavidに知らせてください。


2
Razorの次のバージョンでこれを修正する計画はありますか?これはVS 11 Betaの問題であることに気づきました。
Omar

9

@ジェイクスの答えに似ています:

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


1
これが必要でさえあり、これらがApp_Codeのビューの基本クラスの一部ではないことはばかげています。
Triynko

7

代替ソリューション:

これをrazor-helperファイルの上に追加します。

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

次に、次のように呼び出します。

@HHtml.ActionLink("actionname")

これは最初はうまくいったように見えましたが、ヘルパーを再度呼び出すと、「値が期待される範囲内にありません」というメッセージが表示されました。
d219

3

これに対する私のアプローチは、ページをパラメーターとしてヘルパーメソッドに渡すだけです。したがって、あなたの例では次のようになります:

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

次に、Razorビューで、次のように呼び出します。

@YourHelperFilename.DoSomething(this)

これを行うと、すぐに、HtmlまたはUrl通常持っているような(そしてHtmlHelper拡張機能を介して)ページプロパティにアクセスできます。

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


3

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

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

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


App_Codeの下の.cshtmlのヘルパーがIntellisenseで認識されませんでした。App_codeの下の.cshtmlの上部に@using System.Web.Mvc.Htmlを追加すると機能しました。

これを行うと"Could not load type 'System.Web.WebPages.Instrumentation.InstrumentationService' from assembly 'System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'."、ホバリング時に表示され@using System.Web.Mvcます。何か案は?
JoeBrockhaus 2013

それは私にとって何の違いもありません
mems

0

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

MVC 3 RTMが実現しました。これを使用していますか、それともベータ版ですか?


0

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


いいえ、まったく違います。Intellisenseが拡張メソッドを取得しておらず、VS2013 update 5を持ってい@using System.Web.Mvc.Htmlます。App_Codeのcshtmlファイルの上部にありますが、@ Html ....と書いても、などの拡張メソッドは表示されませんEditorFor。これが2つのメジャーリリースと、それが実装されたと主張するブログ投稿の後に機能しないことは不思議です。そうではありません。実際、拡張メソッドは、System.Web.WebPages.HelperPageクラスによって公開されるSystem.Web.WebPages.HtmlHelperクラスではなく、System.Web.Mvc.HtmlHelperクラスを対象としているため機能しません。
Triynko
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.