web-dev-qa-db-ja.com

ASP.NET MVCでフルURLのアクションを取得する

アクションの完全なURLを取得するための組み込みの方法はありますか?

私はhttp://www.fred.com/Controller/Actionのようなものを返すGetFullUrl("Action", "Controller")のようなものを探しています。

私がこれを探しているのは、自動生成された電子メールでURLがハードコーディングされないようにして、URLが常にサイトの現在の場所から相対的に生成されるようにするためです。

358
Alan Spark

目的のプロトコル(例:http、https)を引数とするUrl.Actionのオーバーロードがあります - これを指定すると、完全修飾URLが取得されます。

これは、現在のリクエストのプロトコルをアクションメソッドで使用する例です。

var fullUrl = this.Url.Action("Edit", "Posts", new { id = 5 }, this.Request.Url.Scheme);

HtmlHelper(@Html)には、アンカー要素を作成するためにかみそりで使用できるActionLinkメソッドのオーバーロードもありますが、hostNameおよびfragmentパラメータも必要です。だから私は再び@ Url.Actionを使うことを選ぶだけです:

<span>
  Copy
  <a href='@Url.Action("About", "Home", null, Request.Url.Scheme)'>this link</a> 
  and post it anywhere on the internet!
</span>
552
Paddy

Paddyが述べたように、使用するプロトコルを明示的に指定するUrlHelper.Action()のオーバーロードを使用する場合、生成されるURLは相対パスではなく絶対パスと完全修飾パスになります。

UrlHelperクラス を使用して絶対アクションURLを作成する方法を読みやすくするためにカスタム拡張メソッドを書くことをお勧めします。

/// <summary>
/// Generates a fully qualified URL to an action method by using
/// the specified action name, controller name and route values.
/// </summary>
/// <param name="url">The URL helper.</param>
/// <param name="actionName">The name of the action method.</param>
/// <param name="controllerName">The name of the controller.</param>
/// <param name="routeValues">The route values.</param>
/// <returns>The absolute URL.</returns>
public static string AbsoluteAction(this UrlHelper url,
    string actionName, string controllerName, object routeValues = null)
{
    string scheme = url.RequestContext.HttpContext.Request.Url.Scheme;

    return url.Action(actionName, controllerName, routeValues, scheme);
}

そうすると、ビューの中でそれを単純に使うことができます。

@Url.AbsoluteAction("Action", "Controller")
131
Marius Schulz

これはあなたがする必要があることです。

@Url.Action(action,controller, null, Request.Url.Scheme)
1
Salman Zahid

この質問はASP .NETに固有のものですが、多くの状況で有益なシステムにとらわれないjavascriptを利用する人もいるでしょう。

更新:ページ自体の外側にURLを作成する方法は、上記の回答で詳しく説明されています。

あるいは、次のような厄介者をすることができます:

new UrlHelper(actionExecutingContext.RequestContext).Action(
    "SessionTimeout", "Home", 
    new {area = string.Empty}, 
    actionExecutingContext.Request.Url!= null? 
    actionExecutingContext.Request.Url.Scheme : "http"
);

フィルタから、または

new UrlHelper(this.Request.RequestContext).Action(
    "Details", 
    "Journey", 
    new { area = productType }, 
    this.Request.Url!= null? this.Request.Url.Scheme : "http"
);

しかし、Html.Actionを使用しているときに、現在のページのURLを取得する必要があることがよくあります。その場合、ページの名前とコントローラを入力すると、厄介に感じます。そのような場合の私の好みは代わりにJavaScriptを使うことです。これは、MVT、Webフォーム、vbスクリプトの半分が書き直されたシステムで特に有効です。現在のページのURLを取得するには、毎回異なる方法を使用する必要があります。

1つの方法はJavaScriptを使用してURLを取得することですwindow.location.hrefもう1つ - document.URL

0

これは私が本当に、本当にうるさいだけかもしれませんが、私は定数を一度だけ定義したいのです。あなたが上で定義されたアプローチのうちのどれかを使うならば、あなたの行動定数は複数回定義されるでしょう。

これを回避するには、次のようにします。

    public class Url
    {
        public string LocalUrl { get; }

        public Url(string localUrl)
        {
            LocalUrl = localUrl;
        }

        public override string ToString()
        {
            return LocalUrl;
        }
    }

    public abstract class Controller
    {
        public Url RootAction => new Url(GetUrl());

        protected abstract string Root { get; }

        public Url BuildAction(string actionName)
        {
            var localUrl = GetUrl() + "/" + actionName;
            return new Url(localUrl);
        }

        private string GetUrl()
        {
            if (Root == "")
            {
                return "";
            }

            return "/" + Root;
        }

        public override string ToString()
        {
            return GetUrl();
        }
    }

それから、例えばDataControllerのように、あなたのコントローラを作成します。

    public static readonly DataController Data = new DataController();
    public class DataController : Controller
    {
        public const string DogAction = "dog";
        public const string CatAction = "cat";
        public const string TurtleAction = "turtle";

        protected override string Root => "data";

        public Url Dog => BuildAction(DogAction);
        public Url Cat => BuildAction(CatAction);
        public Url Turtle => BuildAction(TurtleAction);
    }

それからちょうどそれを使うように:

    // GET: Data/Cat
    [ActionName(ControllerRoutes.DataController.CatAction)]
    public ActionResult Etisys()
    {
        return View();
    }

そしてあなたの.cshtml(または任意のコード)から

<ul>
    <li><a href="@ControllerRoutes.Data.Dog">Dog</a></li>
    <li><a href="@ControllerRoutes.Data.Cat">Cat</a></li>
</ul>

これは間違いなくもっと多くの作業ですが、コンパイル時の検証が私の側にあることを知っているので安心します。

0
Jorge Aguirre

私はこれで問題を抱えていました、私のサーバーはロードバランサーの後ろで走っていました。ロードバランサがSSL/TLS接続を終了していました。それはそれからhttpを使用してWebサーバに要求を渡しました。

Request.Url.Schemaと一緒にUrl.Action()メソッドを使用して、自動URLにリンクを作成するために私の場合はhttp URLを作成し続けました(私のPenTesterは好きではありませんでした)。

私は少し不正をしたかもしれませんが、それはまさに私がhttpsのURLを強制するのに必要だったものです:

<a href="@Url.Action("Action", "Controller", new { id = Model.Id }, "https")">Click Here</a>

私は実際にweb.config AppSettingを使っているので、ローカルでデバッグするときはhttpを使うことができますが、すべてのテスト環境とprod環境は変換を使ってhttps値を設定します。

0
Matt D