ฉันจะรับ URL พื้นฐานของ webapp ใน ASP.NET MVC ได้อย่างไร


300

ฉันจะทราบได้อย่างรวดเร็วว่า URL รูทสำหรับแอปพลิเคชัน ASP.NET MVC ของฉันคืออะไร นั่นคือถ้า IIS ถูกตั้งค่าให้บริการแอปพลิเคชันของฉันที่http://example.com/foo/barดังนั้นฉันจะสามารถรับ URL นั้นในวิธีที่เชื่อถือได้ซึ่งไม่เกี่ยวข้องกับการรับ URL ปัจจุบันจาก ขอและตัดมันด้วยวิธีที่เปราะบางที่แตกถ้าฉันกำหนดเส้นทางการกระทำของฉันอีกครั้ง

เหตุผลที่ฉันต้องการ URL พื้นฐานคือเว็บแอปพลิเคชันนี้เรียกอีกอันหนึ่งที่ต้องการรูทไปยังเว็บแอปพลิเคชันผู้โทรเพื่อใช้ในการโทรกลับ

คำตอบ:


399

สมมติว่าคุณมีวัตถุคำขอพร้อมใช้งานคุณสามารถใช้:

string.Format("{0}://{1}{2}", Request.Url.Scheme, Request.Url.Authority, Url.Content("~"));

หากไม่พร้อมใช้งานคุณสามารถไปที่บริบท:

var request = HttpContext.Current.Request

8
คือurlHelper.Content("~")อะไร ฉันจะสร้างคำจำกัดความได้urlHelperอย่างไร ขอบคุณ!
Maxim Zaslavsky

31
@ Maxim คุณสามารถแทนที่Url.Content ("~")
UpTheCreek

13
สิ่งที่ฉันลงเอยด้วยการใช้:var request = HttpContext.Current.Request; urlBase = string.Format("{0}://{1}{2}", request.Url.Scheme, request.Url.Authority, (new System.Web.Mvc.UrlHelper(request.RequestContext)).Content("~"));
Peter

7
สำหรับ MVC 4 ฉันใช้ControllerContext.RequestContext.HttpContext.Request
row1

7
@Url.Content("~")แก้ไขเป็น"/"ซึ่งไม่ใช่ URL พื้นฐาน
Andrew Hoffman

114

ดังนั้นไม่มีรายการที่นี่ทำงานให้ฉัน แต่ใช้คำตอบบางอย่างฉันได้ทำงาน:

public string GetBaseUrl()
{
    var request = HttpContext.Current.Request;
    var appUrl = HttpRuntime.AppDomainAppVirtualPath;

    if (appUrl != "/") 
        appUrl = "/" + appUrl;

    var baseUrl = string.Format("{0}://{1}{2}", request.Url.Scheme, request.Url.Authority, appUrl);

    return baseUrl;
}

อัพเดทสำหรับ ASP.NET Core / MVC 6:

ASP.NET Coreทำให้กระบวนการนี้เจ็บปวดขึ้นอีกเล็กน้อยโดยเฉพาะอย่างยิ่งถ้าคุณอยู่ลึกเข้าไปในโค้ดของคุณ คุณมี 2 ตัวเลือกที่จะได้รับHttpContext

1) ส่งผ่านจากcontroller:

var model = new MyClass(HttpContext);

จากนั้นในmodel:

private HttpContext currentContext;

public MyClass(HttpContext currentContext)
{
    this.currentContext = currentContext;
}

2) บางทีวิธีที่สะอาดกว่านี้คือการฉีดเข้าไปในชั้นเรียนของคุณซึ่งเริ่มต้นด้วยการลงทะเบียนประเภทในของคุณ Startup:

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddMvc();

    services.AddTransient<MyClass, MyClass>();
    services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}

จากนั้นให้ฉีดให้คุณดังนี้:

private HttpContext currentContext;

public MyClass(IHttpContextAccessor httpContextAccessor)
{
    currentContext = httpContextAccessor.HttpContext;
}

ในกรณีใดกรณีหนึ่งนี่คือการอัปเดตสำหรับ.NET Core GetBaseUrl():

public string GetBaseUrl()
{
    var request = currentContext.Request;

    var host = request.Host.ToUriComponent();

    var pathBase = request.PathBase.ToUriComponent();

    return $"{request.Scheme}://{host}{pathBase}";
}

คุณวางวิธีนี้ไว้ที่ไหน
Josh Dean

3
ขึ้นอยู่กับว่าคุณต้องใช้บ่อยแค่ไหน ... ถ้านี่เป็นดีลการใช้งานครั้งเดียวคุณแค่วางมันไว้ในคลาสที่คุณต้องการข้อมูลนี้ถ้าคุณคาดว่าจะใช้มันในหลาย ๆ คลาสในแอพของคุณ โฟลเดอร์ที่เรียกว่าHelpersในฐานของ app ของฉันที่ฉันมีstaticระดับที่เรียกว่าStaticsและฉันใส่ฟังก์ชั่นเหมือนข้างต้นมี ... เพียงให้แน่ใจว่าคุณเปลี่ยนข้างต้นจากpublic string GetBaseUrl()ไปpublic static string GetBaseUrl()
Serj เซแกน

เป็นการอัปเดตฉันไม่ใช้คลาสที่เรียกอีกต่อไปStaticsแต่ฉันแยกมันออกเป็นการใช้งานที่เฉพาะเจาะจงมากขึ้นดังนั้นในกรณีนี้มันจะเข้าสู่UrlHelperชั้นเรียนของฉัน
Serj Sagan

1
ตัวเลือกทั้งหมดที่ฉันได้พบนี้เป็นตัวเลือกเดียวที่ใช้งานได้จริงสำหรับฉัน อันดับที่ 2 ของคุณคือ ขอบคุณมัด!
adeldegan

2
อัปเดตสิ่งนี้เพราะเป็นเพียงสิ่งเดียวที่พูดถึง PathBase ซึ่งเป็นสิ่งที่ฉันต้องการ ขอบคุณ!
เดฟ

69

ในรหัส:

Url.Content("~/");

ไวยากรณ์มีดโกน MVC3:

@Url.Content("~/")

11
นี่เป็นสิ่งที่ดีสำหรับการใช้ในหน้ามีดโกน แต่ถ้าคุณพยายามส่ง URL ไปยังแหล่งข้อมูลภายนอกจะไม่ให้ URL แบบเต็มกับคุณ
krillgar

5
มันไม่ทำงาน มันจะเพิ่ม/แทนชื่อจริง
Mrchief

2
อยู่ที่ไหนรหัสไม่Urlช่วยที่มีให้คุณขวาปิดค้างคาว? Controllerบางทีเฉพาะใน ไม่แน่นอนในViewModelหรืออื่น ๆclassที่คุณอาจจำเป็นต้องใช้นี้ ..
34816 Serj Sagan

43

อาจเป็นส่วนขยายหรือแก้ไขคำตอบที่โพสต์ไว้ที่นี่ แต่ฉันใช้เพียงบรรทัดต่อไปนี้และทำงานได้:

Request.Url.GetLeftPart(UriPartial.Authority) + Url.Content("~")

เมื่อเส้นทางของฉันคือ: http://host/iis_foldername/controller/action
แล้วฉันจะได้รับ:http://host/iis_foldername/


26

ตัวอย่างต่อไปนี้ทำงานได้ดีสำหรับฉันใน MVC4 และไม่จำเป็นต้องHttpContextมี:

System.Web.HttpRuntime.AppDomainAppVirtualPath

ดูเหมือนว่าจะทำงานใน MVC3 เช่นกัน ฉันใช้มันในjQuery.load()การสร้าง URL สำหรับคอนโทรลเลอร์และแอ็คชันที่ฉันต้องการเรียกใช้: $('#myplaceholder').load('@(Html.Raw(HttpRuntime.AppDomainAppVirtualPath))/MyController/MyAction', ...);
Kjell Rilbe

ทำไมคุณจะทำเช่นนั้น? แทนที่จะเรียก Url.Action?
BlackTigerX

4
ไม่ทำงานเมื่อปรับใช้กับ Azure คำตอบที่ได้รับคะแนนสูงกว่าจะทำงานในสถานการณ์นี้
Jeff Dunlop

25

เคล็ดลับในการใช้ IIS คือการผูก IIS อาจแตกต่างจาก URL สาธารณะของคุณ (WCF ฉันกำลังมองคุณอยู่) โดยเฉพาะกับเครื่องที่ใช้งานหลายบ้าน ฉันมักจะเวกเตอร์ไปสู่การใช้การกำหนดค่าเพื่อกำหนด url "ฐาน" สำหรับวัตถุประสงค์ภายนอกอย่างชัดเจนเนื่องจากมีแนวโน้มที่จะประสบความสำเร็จมากกว่าการแยกจากคำขอวัตถุ


2
เป็นจริงสำหรับเซิร์ฟเวอร์ที่อยู่เบื้องหลัง load balancer หรือพรอกซี
Ishmaeel

20

สำหรับ URL ฐานสัมบูรณ์ให้ใช้สิ่งนี้ ทำงานได้กับทั้ง HTTP และ HTTPS

new Uri(Request.Url, Url.Content("~"))

15

นี่คือการเปลี่ยนแปลงของสถานที่ให้บริการที่จะ asp.net MVC มันเป็นวิธีการร้องเพลงการเต้นรำทั้งหมดได้รับการรูท URL

ประกาศคลาสผู้ช่วย:

namespace MyTestProject.Helpers
{
    using System.Web;

    public static class PathHelper
    {
        public static string FullyQualifiedApplicationPath(HttpRequestBase httpRequestBase)
        {
            string appPath = string.Empty;

            if (httpRequestBase != null)
            {
                //Formatting the fully qualified website url/name
                appPath = string.Format("{0}://{1}{2}{3}",
                            httpRequestBase.Url.Scheme,
                            httpRequestBase.Url.Host,
                            httpRequestBase.Url.Port == 80 ? string.Empty : ":" + httpRequestBase.Url.Port,
                            httpRequestBase.ApplicationPath);
            }

            if (!appPath.EndsWith("/"))
            {
                appPath += "/";
            }

            return appPath;
        }
    }
}

การใช้งาน:

วิธีใช้จากคอนโทรลเลอร์:

PathHelper.FullyQualifiedApplicationPath(ControllerContext.RequestContext.HttpContext.Request)

วิธีใช้ในมุมมอง:

@using MyTestProject.Helpers

PathHelper.FullyQualifiedApplicationPath(Request)

1
นี่เป็นคำตอบเดียวที่อธิบายถึงความเป็นไปได้ของเว็บไซต์ที่ทำงานบนพอร์ตอื่นที่ไม่ใช่ 80 คำตอบอื่น ๆ ทั้งหมดนั้นไม่ปลอดภัยเท่าที่ฉันกังวล ขอบคุณ!
jebar8

12

ใน MVC _Layout.cshtml:

<base href="@Request.GetBaseUrl()" />

นั่นคือสิ่งที่เราใช้!

public static class ExtensionMethods
{
public static string GetBaseUrl(this HttpRequestBase request)
        {
          if (request.Url == (Uri) null)
            return string.Empty;
          else
            return request.Url.Scheme + "://" + request.Url.Authority + VirtualPathUtility.ToAbsolute("~/");
        }
}

+1 <base>สำหรับใช้ นอกจากนี้คุณสามารถละเว้น Scheme เพื่อให้ทำงานได้กับ http หรือ https นั่นหมายความว่าคุณสามารถเริ่มต้น URL //ด้วย
Jess

5

มันใช้งานได้ดีสำหรับฉัน (เช่นกันกับ load balancer):

@{
    var urlHelper = new UrlHelper(Html.ViewContext.RequestContext);
    var baseurl = urlHelper.Content(“~”);
}

<script>
    var base_url = "@baseurl";
</script>

โดยเฉพาะอย่างยิ่งถ้าคุณใช้หมายเลขพอร์ตที่ไม่เป็นมาตรฐานการใช้ Request.Url.Authority จะปรากฏขึ้นเหมือนกับมีโอกาสในการขายที่ดีในตอนแรก แต่ล้มเหลวในสภาพแวดล้อม LB


3

คุณอาจมีวิธีการคงที่ที่ดูที่ HttpContext.Current และตัดสินใจว่าจะใช้ URL ใด (การพัฒนาหรือเซิร์ฟเวอร์ที่ใช้งานจริง) ขึ้นอยู่กับ ID โฮสต์ HttpContext อาจเสนอวิธีที่ง่ายกว่าในการทำสิ่งนี้ แต่นี่เป็นตัวเลือกแรกที่ฉันพบและใช้งานได้ดี


3

คุณสามารถใช้สคริปต์ต่อไปนี้ในมุมมอง:

<script type="text/javascript">
    var BASE_URL = '<%= ResolveUrl("~/") %>';
</script>


3

สิ่งนี้ใช้งานได้ใน ASP .NET MVC 4 ในการดำเนินการควบคุมใด ๆ ที่คุณสามารถเขียนได้: 1stline รับ url ทั้งหมด + Query String บรรทัดที่ 2 ลบเส้นทาง & เคียวรีโลคอลสัญลักษณ์ '/' สุดท้าย บรรทัดที่ 3 เพิ่มสัญลักษณ์ '/' ที่ตำแหน่งสุดท้าย

Uri url = System.Web.HttpContext.Current.Request.Url;
string UrlLink = url.OriginalString.Replace(url.PathAndQuery,"");
UrlLink = String.Concat(UrlLink,"/" );


3

สำหรับ URL ที่มีชื่อแทนแอปพลิเคชันเช่นhttp://example.com/appAlias/ ... คุณสามารถลองนี้:

var req = HttpContext.Current.Request;
string baseUrl = string.Format("{0}://{1}/{2}", req.Url.Scheme, req.Url.Authority, req.ApplicationPath);

3

บนหน้าเว็บ:

<input type="hidden" id="basePath" value="@string.Format("{0}://{1}{2}",
  HttpContext.Current.Request.Url.Scheme,
  HttpContext.Current.Request.Url.Authority,
  Url.Content("~"))" />

ในจาวาสคริปต์:

function getReportFormGeneratorPath() {
  var formPath = $('#reportForm').attr('action');
  var newPath = $("#basePath").val() + formPath;
  return newPath;
}

สิ่งนี้ใช้ได้กับโครงการ MVC ของฉันหวังว่าจะช่วยได้


@hemp แก้ไขแล้ว แต่ไม่ได้ลงคะแนนหรือ หวังว่าคะแนนเหล่านี้มีค่าสำหรับคุณ
Andrew Day

คำถามนี้และคำตอบที่เกี่ยวข้องไม่เป็นประโยชน์สำหรับปัญหาเฉพาะของฉันดังนั้นฉันจึงไม่ได้ลองหรือลงคะแนนให้พวกเขาเลย ฉันแก้ไขสิ่งนี้เพราะฉันเห็นมันเกิดขึ้นและคิดว่ามันอาจเป็นคำตอบที่ดีถ้ามันถูกฟอร์แมตอย่างถูกต้อง แค่พยายามเป็นพลเมืองที่ดี
ป่าน

นอกจากนี้ยังไม่มีคะแนนชื่อเสียงที่ได้รับสำหรับการแก้ไขคำตอบ
ป่าน


2

บางทีมันอาจเป็นทางออกที่ดีกว่า

@{
   var baseUrl = @Request.Host("/");
}

การใช้

<a href="@baseUrl" class="link">Base URL</a>

1
ฉันไม่ได้ทดสอบ แต่ฉันสงสัยว่ามันจะทำงานเมื่อ url พื้นฐานเป็นเสมือนโดยตรง กล่าวคือ localhost / myApp
emragins


1

ต่อไปนี้ทำงานอย่างสมบูรณ์สำหรับฉัน

var request = HttpContext.Request;
                        var appUrl = System.Web.HttpRuntime.AppDomainAppVirtualPath;

                        if (appUrl != "/")
                            appUrl = "/" + appUrl + "/";

                        var newUrl = string.Format("{0}://{1}{2}{3}/{4}", request.Url.Scheme, request.UrlReferrer.Host, appUrl, "Controller", "Action");


1

นี่คือโซลูชันของฉัน (ใช้. net core 3.1 ในตัวควบคุม api):

string baseUrl = $"{Request.Scheme}://{Request.Headers.Where(h => h.Key == "Host").First().Value}";

0

เพียงแค่ในบรรทัดเดียวรับ BaseUrl

string baseUrl = new Uri(Request.Url, Url.Content("~")).AbsoluteUri;

//output example: https://stackoverflow.com

0

นอกจากนี้คุณสามารถใช้สิ่งนี้ สำหรับหน้ามีดโกนมันจะดีกว่าที่จะใช้มันกว่าคนอื่น ๆ

https://ml-software.ch/posts/getting-the-base-url-for-an-asp-net-core-mvc-web-application-in-your-static-javascript-files

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <base href='@Url.AbsoluteContent("~/")'>
    <title>@ViewBag.Title - ASP.NET Core Web Application</title>
    <!-- ... -->
</head>
<body>

0

เพิ่มฟังก์ชั่นนี้ในคลาสสแตติกในโครงการเช่นคลาสยูทิลิตี้:

ยูทิลิตี้. csเนื้อหา:

public static class Utility
{
    public static string GetBaseUrl()
    {
        var request = HttpContext.Current.Request;
        var urlHelper = new UrlHelper(request.RequestContext);
        var baseUrl = $"{request.Url.Scheme}://{request.Url.Authority}{urlHelper.Content("~")}";
        return baseUrl;
    }
}

ใช้รหัสนี้ทุกที่และสนุกกับมัน:

var baseUrl = Utility.GetBaseUrl();
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.