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でこれを難しくするつもりですか、それとも何か間違ったことをしていますか?
この質問に対する Marcind
's answer をご覧ください。あなたが経験しているのは、App_Code
フォルダーに宣言的なビューを置くことの制限です。
ヘルパーをApp_Codeに配置することはできますが、特定のMVCシナリオに影響する特定の制限があります(たとえば、標準のMVC Htmlヘルパーにアクセスできません)。
ページヘルパーにアクセスできるように、WebPagesヘルパーの拡張メソッドを作成しました。
public static HtmlHelper GetPageHelper(this System.Web.WebPages.Html.HtmlHelper html)
{
return ((System.Web.Mvc.WebViewPage) WebPageContext.Current.Page).Html;
}
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
それを試して、あなたの考えを見てください!ブログに投稿して、コメントがあるかどうかデビッドに知らせてください。
@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
代替ソリューション:
あなたのrazor-helperファイルの上にこれを追加してください:
@functions {
public static System.Web.Mvc.HtmlHelper<object> HHtml = ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Html;
}
次のように呼び出します:
@HHtml.ActionLink("actionname")
検索者の利益のために、MVCビューをクラスライブラリの一部として作成するときに同じエラーが発生しました(コンポーネントの再利用のため)。上記で部分的に示唆された解決策は、.cshtmlファイルの先頭に次のusingステートメントを追加することでした。
@using System.Web.Mvc
@using System.Web.Mvc.Html
これ以上の作業は必要ありません。
これへの私のアプローチは、ページをヘルパーメソッドへのパラメーターとして単に渡すことです。したがって、あなたの例では:
@helper DoSomething(WebViewPage page)
{
@page.Html.ActionLink("Index", "Home")
}
次に、Razorビューで必要な場所で次のように呼び出します。
@YourHelperFilename.DoSomething(this)
これをすぐに行うと、通常持っているHtml
やUrl
などのページプロパティにアクセスできます(これにより、HtmlHelper
拡張機能)。
追加の利点として(必要な場合)、ページのViewData
などのインスタンスプロパティにもアクセスできます。
ASP.NET MVCがVS 2013でこの問題を修正したようです。この投稿を参照してください http://aspnet.uservoice.com/forums/41201-asp-net-mvc/suggestions/3670180-support-helper- extensionmethod-this-htmlhelper-ht
MVC 3にはいくつかのインテリセンスの問題があることを知っています。web.configで名前空間を設定していれば、ヘルパーは引き続き機能すると思います。
MVC 3 RTMは、これまたはベータ版を使用していますか?