HTMLヘルパーでURLを生成する


168

通常、ASP.NETビューでは、次の関数を使用して(ではなく<a>)URLを取得できます。

Url.Action("Action", "Controller");

しかし、カスタムHTMLヘルパーからそれを行う方法を見つけることができません。私が持っています

public class MyCustomHelper
{
   public static string ExtensionMethod(this HtmlHelper helper)
   {
   }
}

ヘルパー変数にはActionメソッドとGenerateLinkメソッドがありますが、それらはを生成し<a>ます。ASP.NET MVCソースコードを掘り下げましたが、簡単な方法が見つかりませんでした。

問題は、上のUrlがビュークラスのメンバーであり、そのインスタンス化のためにいくつかのコンテキストとルートマップが必要であることです(これについては扱いたくないので、とにかく想定していません)。あるいは、HtmlHelperクラスのインスタンスにもいくつかのコンテキストがあります。これは、Urlインスタンスのコンテキスト情報のサブセットの夕食のいずれかであると想定しています(ただし、これについては扱いたくありません)。

要約すると、それは可能だと思いますが、私が見ることができるすべての方法は、多少の内部ASP.NET要素による操作を伴うため、より良い方法があるかどうか疑問に思います。

編集:たとえば、私が見る可能性の1つは次のとおりです。

public class MyCustomHelper
{
    public static string ExtensionMethod(this HtmlHelper helper)
    {
        UrlHelper urlHelper = new UrlHelper(helper.ViewContext.RequestContext);
        urlHelper.Action("Action", "Controller");
    }
}

しかし、それは正しくないようです。私はUrlHelperのインスタンスを自分で処理したくありません。もっと簡単な方法があるはずです。


3
これは単純化された例であることに気づきましたが、示されている例では、HtmlHelperではなくUrlHelperを拡張します。ただし、実際のコードでは両方が必要になる場合があります。
Craig Stuntz

申し訳ありませんが、もっと明確にしておく必要がありました。拡張メソッドでHTMLレンデティングを実行したかったので、そのためのURLを生成する必要がありました。
Jan Zich

回答:


217

HTMLヘルパー拡張メソッド内に次のようなURLヘルパーを作成できます。

var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
var url = urlHelper.Action("Home", "Index")

2
コンストラクターもRouteCollectionを初期化するほうがよいと思いますnew UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection)
kpull1

22

UrlHelperpublicおよびstaticクラスを使用してリンクを取得することもできます。

UrlHelper.GenerateUrl(null, actionName, controllerName, null, null, null, routeValues, htmlHelper.RouteCollection, htmlHelper.ViewContext.RequestContext, true)

この例では、少し有利になる可能性のある新しいUrlHelperクラスを作成する必要はありません。


RouteCollectionを設定するので、私はこの答えがより好きです。
kpull1 2015

10

ここで取得するために私の小さなextenstion方法でUrlHelperHtmlHelperインスタンスは:

  public static partial class UrlHelperExtensions
    {
        /// <summary>
        /// Gets UrlHelper for the HtmlHelper.
        /// </summary>
        /// <param name="htmlHelper">The HTML helper.</param>
        /// <returns></returns>
        public static UrlHelper UrlHelper(this HtmlHelper htmlHelper)
        {
            if (htmlHelper.ViewContext.Controller is Controller)
                return ((Controller)htmlHelper.ViewContext.Controller).Url;

            const string itemKey = "HtmlHelper_UrlHelper";

            if (htmlHelper.ViewContext.HttpContext.Items[itemKey] == null)
                htmlHelper.ViewContext.HttpContext.Items[itemKey] = new UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection);

            return (UrlHelper)htmlHelper.ViewContext.HttpContext.Items[itemKey];
        }
    }

次のように使用します。

public static MvcHtmlString RenderManagePrintLink(this HtmlHelper helper, )
{    
    var url = htmlHelper.UrlHelper().RouteUrl('routeName');
    //...
}

(私は参考のためにこのansを投稿しています)


新しいオブジェクトを作成するのではなく、既存のオブジェクトを再利用するため、優れたアプローチです。
Mike

私たちはASP.NET 4.5を使用しており、再入問題が発生していました。UrlHelperがhttpリクエスト全体で再利用できるとは考えていません。気をつけてください。
't Veld
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.