自分の HtmlHelper 内から HtmlHelper メソッドにアクセスするにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/494345

  •  20-08-2019
  •  | 
  •  

質問

私は ASP.NET MVC 用に独自の HtmlHelper 拡張機能を作成しています。

public static string CreateDialogLink (this HtmlHelper htmlHelper, string linkText, 
                                      string contentPath)
        {
            // fix up content path if the user supplied a path beginning with '~'
            contentPath = Url.Content(contentPath);  // doesn't work (see below for why)

            // create the link and return it
            // .....
        };

アクセスしようとして問題が発生しているのは UrlHelper から 内で 私のHtmlHelperの定義。問題は、通常のアクセス方法では HtmlHelper (経由 Html.MethodName(...) ) は、ビューのプロパティ経由です。これは、私自身の拡張クラスからは明らかに利用できません。

これは実際の MVC ソース コードです。 ViewMasterPage (ベータ時点) - 定義 Html そして Url.

public class ViewMasterPage : MasterPage
    {
        public ViewMasterPage();

        public AjaxHelper Ajax { get; }
        public HtmlHelper Html { get; }
        public object Model { get; }
        public TempDataDictionary TempData { get; }
        public UrlHelper Url { get; }
        public ViewContext ViewContext { get; }
        public ViewDataDictionary ViewData { get; }
        public HtmlTextWriter Writer { get; }
    }

HtmlHelper 内でこれらのプロパティにアクセスできるようにしたいと考えています。

私が思いついた最高のものはこれです(最初に挿入) CreateDialogLink 方法)

HtmlHelper Html = new HtmlHelper(htmlHelper.ViewContext, htmlHelper.ViewDataContainer);
UrlHelper Url = new UrlHelper(htmlHelper.ViewContext.RequestContext);

既存のファイルにアクセスする他の方法が見つからないのでしょうか? HtmlHelper そして UrlHelper インスタンス - それとも本当に新しいインスタンスを作成する必要がありますか?オーバーヘッドはそれほど多くないとは思いますが、可能であれば既存のものを使用したいと思います。

役に立ちましたか?

解決

この質問をする前に、MVC ソース コードの一部を調べましたが、明らかにこれを見逃していました。これが、イメージ ヘルパーの場合の方法です。

[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#", Justification = "The return value is not a regular URL since it may contain ~/ ASP.NET-specific characters")]
        public static string Image(this HtmlHelper helper, string imageRelativeUrl, string alt, IDictionary<string, object> htmlAttributes) {
            if (String.IsNullOrEmpty(imageRelativeUrl)) {
                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "imageRelativeUrl");
            }

            UrlHelper url = new UrlHelper(helper.ViewContext);
            string imageUrl = url.Content(imageRelativeUrl);
            return Image(imageUrl, alt, htmlAttributes).ToString(TagRenderMode.SelfClosing);
        }

新しいインスタンスを作成しているようです UrlHelper 結局のところ正しいアプローチです。私にとってはそれで十分です。


アップデート: RTM コードのソース ASP.NET MVC v1.0 ソース コード コメントで指摘されているように、少し異なります。

ファイル:MVC\src\MvcFutures\Mvc\ImageExtensions.cs

 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#", Justification = "The return value is not a regular URL since it may contain ~/ ASP.NET-specific characters")]
        public static string Image(this HtmlHelper helper, string imageRelativeUrl, string alt, IDictionary<string, object> htmlAttributes) {
            if (String.IsNullOrEmpty(imageRelativeUrl)) {
                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "imageRelativeUrl");
            }

            UrlHelper url = new UrlHelper(helper.ViewContext.RequestContext);
            string imageUrl = url.Content(imageRelativeUrl);
            return Image(imageUrl, alt, htmlAttributes).ToString(TagRenderMode.SelfClosing);
        }

他のヒント

私は同様の問題に直面し、それだけでビューにUrlHelperを呼び出し、私のHtmlHelperの拡張に出力を渡すために容易になるだろうことを決めました。あなたのケースでは、それは次のようになります:

<%= Html.CreateDialogLink( "text", Url.Content( "~/...path.to.content" ) ) %>
あなたのクラスに渡され、既存のHtmlHelperの拡張メソッドにアクセスしたい場合は、

、それはどこだ(あなたは、あなたのソースコードファイルにSystem.Web.Mvc.Htmlをインポートする必要がある必要がありますし、それらへのアクセスを取得します拡張機能クラスが定義されています)。あなたがUrlHelperをしたい場合、あなたはHtmlHelperのようあなたはそれがから来ることをビューページのハンドルを持っていない取得していることをインスタンス化する必要があります。

あなたはユーティリティクラスでUrlHelperを作成する必要がある場合は、次の操作を行うことができます:

の文字列のURL = "〜/コンテンツ/画像/ foo.jpgという";

  var urlHelper = new UrlHelper(new RequestContext(
                  new HttpContextWrapper(HttpContext.Current), 
                  new RouteData()), RouteTable.Routes);

  string absoluteUrl = urlHelper.Content(url);

これはMVCのコンテキストから離れルーティングや「〜の拡張」を使用することができます。

さて、あなたは常に拡張メソッドにページのインスタンスを渡すことができます。私はそれがあなたの方法で新しいインスタンスを作成するよりも、これを行うためのより良い方法だと思います。

また、マスターページ/ ViewMasterPageから派生するクラスでこのメソッドを定義し、そこからページを引き出すことができます。この方法で、あなたは、インスタンスのすべてのプロパティへのアクセス権を持っており、それらを周りに渡す必要はありません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top