2010-01-05 6 views
325

동작의 전체 URL을 가져 오는 기본 제공 방법이 있습니까?ASP.NET MVC에서 전체 동작 URL 받기

http://www.fred.com/Controller/Action과 같은 것을 반환하는 GetFullUrl("Action", "Controller")과 같은 것을 찾고 있습니다.

내가 찾고있는 이유는 URL이 항상 사이트의 현재 위치에 상대적으로 생성 될 수 있도록 생성 된 자동화 된 전자 메일에서 URL을 하드 코딩하는 것을 피하기 위해서입니다.

+0

도 참조하십시오 : http://stackoverflow.com/q/434604 – Andrew

답변

503

원하는 프로토콜 (예 : http, https)을 인수로 사용하는 Url.Action 오버로드가 있습니다.이를 지정하면 정규화 된 URL이 생성됩니다. 여기

는 액션 메소드에서 현재 요청의 프로토콜을 사용하는 예입니다 :

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

Html 헬퍼 (@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> 
+4

아니요.이 작업을 수행하는 더 좋은 방법이 있어야한다고 생각 하겠지만, 어쩌면 ... – Paddy

+0

Azure 에뮬레이터로 로컬에서 테스트 할 때 올바른 포트 81 대신 포트 82를 반환합니다. 게시되거나 게시되지 않을 때 제대로 작동하는지 확실하지 않습니다. Marius Schulz가 제안한 대답은 완벽하게 작동합니다. – angularsen

+1

오른쪽 URL은'https : // 127.0.0.1/Home/Index'이지만'https : //127.0.0.1 : 444/Home/Index'를 생성합니다. 포트가 없어야합니다. 나는 Azure 에뮬레이터에서 실행 중입니다. 도와주세요. – fiberOptics

123

패디가 언급 한 바와 같이 : 를 명시 적으로 사용하는 프로토콜을 지정 UrlHelper.Action()의 오버로드를 사용하는 경우, 생성 된 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); 
} 

당신은 단순히보기에 그런 식으로 사용할 수 있습니다 :

은 내가 가독성을 위해서 사용자 정의 확장 메서드를 작성하는 것이 좋습니다있는 How to build absolute action URLs using the UrlHelper class라는 블로그 포스트를 작성

@Url.AbsoluteAction("Action", "Controller") 
+0

당신이 더 upvotes있어, 사실 이것은 프레임 워크에 있어야한다는 생각할 필요가 없습니다 IMO – Roger

+7

내가 추가 (또는 수정)하는 유일한 것은 HttpContext.Current.Request.Url.Scheme로 리터럴 "http"를 대체하는 것입니다 . 이렇게하면 적절한 경우 https를 사용할 수 있습니다. – Jay

+0

@Jay, 귀하의 제안에 감사드립니다, 내 코드 예제를 업데이트했습니다. 내 블로그 게시물에 대한 동일한 의견을 받았습니다 ;-). –

0

이 질문은 ASP .NET에만 해당됩니다. 그러나 많은 사람들이 도움이되는 시스템 무신론자 JavaScript의 이점을 누릴 수 있습니다.

업데이트 : 페이지 외부에 형성된 URL을 얻는 방법은 위의 답변에 잘 설명되어 있습니다.

또는 당신은 다음과 같은 oneliner을 할 수있는 :

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 절반 웹 폼 절반 VB 스크립트 절반 하나님은 현재 페이지의 URL을 얻으려면 매번 다른 방법을 사용해야합니다. document.URL

+1

이것은 현재 페이지의 URL을 표시하는 데에만 작용합니다. OP가하고 싶어하는 것은 .Net 컨트롤러와 뷰의 이름을 전달하여 해당 페이지로 이동하는 URL을 생성하는 것입니다. – Matthew

0

이 그냥 날 정말, 정말 까다롭게 될 수있다,하지만 난 한 번만 상수를 정의하고자 -

한 가지 방법은 URL을 얻을 자바 스크립트를 사용하는 것입니다 window.location.href 또 다른입니다. 위에 정의 된 접근법 중 하나를 사용하면 활동 상수가 여러 번 정의됩니다.

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 :

것은이 문제를 방지하려면 다음을 수행 할 수 있습니다

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

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); 
    } 

그럼 그냥 좋아 사용

.cshtml (또는 다른 코드)

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

이것은 훨씬 더 많은 작업이지만 컴파일 시간 유효성 검사가 편하다고 생각합니다.

1

이 작업을 수행해야합니다.

@Url.Action(action,controller, null, Request.Url.Scheme) 
+2

허용되는 답변과 동일합니다. 답변은 새로운 것이 도입되었을 때 가장 잘 게시됩니다. – Doomsknight

0

이 문제는 내 부하 분산 장치 뒤에 있습니다. 로드 밸런서가 SSL/TLS 연결을 종료했습니다. 그런 다음 http를 사용하여 웹 서버에 요청을 전달했습니다.

Request.Url.Schema와 함께 Url.Action() 메서드를 사용하여, 내 경우에 자동 URL (내 PenTester에서 마음에 들지 않았 음)로 링크를 만드는 데 계속해서 http url을 만들었습니다.

내가 조금 사기 모르지만, 그것이 내가이 된 HTTPS URL 강제하기 위해 필요한 정확히 :

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

가 실제로 로컬 디버깅 할 때 HTTP를 사용할 수 있도록 AppSetting Web.config의를 사용을하지만, 모든 test 및 prod 환경은 변환을 사용하여 https 값을 설정합니다.