รับ URL ดิบจาก Microsoft.AspNet.Http.HttpRequest


89

HttpRequestชั้นใน Asp.Net 5 (vNext) มี (ในหมู่สิ่งอื่น ๆ ) รายละเอียดเกี่ยวกับการแยกวิเคราะห์ URL สำหรับคำขอเช่นScheme, Host, Pathฯลฯ

ฉันยังไม่พบที่ใดที่เปิดเผย URL คำขอเดิม - เฉพาะค่าที่แยกวิเคราะห์เหล่านี้ (ในรุ่นก่อนหน้านี้มีRequest.Uri)

ฉันสามารถรับ URL ดิบกลับมาโดยไม่ต้องรวมเข้าด้วยกันจากส่วนประกอบที่มีอยู่ใน HttpRequest ได้หรือไม่


1
ดูเหมือนว่าจะมีการแจ้งข้อบกพร่องก่อนหน้านี้เกี่ยวกับเรื่องนี้ แต่ปิดไปแล้ว ... คุณสามารถตรวจสอบรายละเอียดของมันได้และหากคุณรู้สึกดีขึ้นเกี่ยวกับเรื่องนี้อาจอัปเดตโดยมีรายละเอียด: github.com/aspnet/HttpAbstractions/issues/110
Kiran Challa

@KiranChalla: ฉันใช้ประเด็นของพวกเขาแม้ว่ามันจะทำให้ฉันสงสัยว่า RawURL ในเวอร์ชันก่อนหน้านั้นเป็นอย่างไร ฉันเดาว่าพวกเขากำลังแสดงอะไรเกี่ยวกับโครงร่างโฮสต์และอื่น ๆ สามารถแบ่งออกได้จากการจัดการด้านเซิร์ฟเวอร์ของคำขอไม่ใช่สิ่งใดในคำขอ
Jon Egerton

คุณลอง ToString () หรือไม่
กัวจาก

คำตอบ:


85

ดูเหมือนว่าคุณไม่สามารถเข้าถึงได้โดยตรง แต่คุณสามารถสร้างได้โดยใช้กรอบ:

Microsoft.AspNetCore.Http.Extensions.UriHelper.GetFullUrl(Request)

คุณยังสามารถใช้ข้างต้นเป็นวิธีการขยาย

สิ่งนี้ส่งคืนstringมากกว่า a Uriแต่ควรตอบสนองวัตถุประสงค์! (ดูเหมือนว่าจะรับใช้บทบาทของUriBuilderมันด้วย)

ขอบคุณ @mswietlicki ที่ชี้ให้เห็นว่าเพิ่งได้รับการปรับโครงสร้างใหม่แทนที่จะหายไป! และยัง @CF เพื่อชี้ให้เห็นการเปลี่ยนแปลงเนมสเปซในคำตอบของฉัน!


4
สิ่งนี้ใช้ไม่ได้อีกต่อไปเมื่อเบต้า -5 ฉันไม่มีทางเลือกที่ดีหรือจะปรับปรุงคำตอบของฉัน
Matt DeKrey

13
ฉันเชื่อว่านี่เป็นวิธีการขยายที่แท้จริง - คุณเพียงแค่นำเข้าเนมสเปซและเรียกใช้GetEncodedUriหรือGetDisplayUriขึ้นอยู่กับกรณีการใช้งานของคุณ
dlras2

43
โดยใช้ Microsoft.AspNet.Http.Extensions; และ
คำขอนั้น GetDisplayUrl

8
ตอนนี้เนมสเปซที่เหมาะสมคือ Microsoft.AspNetCore.Http.Extensions
CF

9
สำหรับ ASP.NET Core 1.0 เพิ่มโดยใช้ "Microsoft.AspNetCore.Http.Extensions" ในมุมมอง Razor ของคุณ ในการรับ url ให้ใช้ "@ Context.Request.GetDisplayUrl ()"
Joop

75

เพิ่มแพ็คเกจ Nuget / ใช้:

using Microsoft.AspNetCore.Http.Extensions; 

(ใน ASP.NET Core RC1 สิ่งนี้อยู่ใน Microsoft.AspNet.Http.Extensions)

จากนั้นคุณจะได้รับ URL คำขอ http แบบเต็มโดยดำเนินการ:

var url = httpContext.Request.GetEncodedUrl();

หรือ

var url = httpContext.Request.GetDisplayUrl();

ขึ้นอยู่กับวัตถุประสงค์


ASP.NET Core RC2 พร้อมใช้งานแล้วหรือยัง
Sergey G.


เมื่อมองไปที่แหล่งที่มาสิ่งเหล่านี้ทำการเข้ารหัส / ถอดรหัสอย่างชัดเจนดังนั้นนี่จะไม่ใช่ URL ดิบ นอกจากนี้ IIS จะเปลี่ยนบางครั้งเปลี่ยน url ก่อนที่จะเปลี่ยนเป็น Kestrel เช่น% 2F -> /
Daniel Leach

1
@TomStickel ไม่แน่ใจว่าคุณกำลังพูดถึงอะไร ... ฉันไม่มีปัญหาในการใช้อย่างใดอย่างหนึ่ง ตรวจสอบว่าคุณมีusingคำสั่งในไฟล์ตามที่อธิบายไว้ในคำตอบเนื่องจากวิธีเหล่านี้ไม่ใช่วิธี "ปกติ" แต่เป็นวิธีการขยาย
Nick Mertin

1
@TomStickel ยุติธรรม. เพียงสังเกตว่าด้วย Microsoft.AspNetCore แพ็คเกจทั้งหมดที่ติดตั้งสำหรับ ASP.NET Core 2.2 (ทดสอบด้วย 2.0) มันใช้งานได้ดีสำหรับฉัน
Nick Mertin

16

หากคุณจริงๆต้องการที่เกิดขึ้นจริง URL ดิบคุณสามารถใช้วิธีการขยายต่อไปนี้:

public static class HttpRequestExtensions
{
    public static Uri GetRawUrl(this HttpRequest request)
    {
        var httpContext = request.HttpContext;

        var requestFeature = httpContext.Features.Get<IHttpRequestFeature>();

        return new Uri(requestFeature.RawTarget);
    }
}

วิธีนี้ใช้การRawTargetร้องขอซึ่งไม่ปรากฏบนHttpRequestวัตถุเอง คุณสมบัตินี้ถูกเพิ่มใน ASP.NET Core รุ่น 1.0.0 ตรวจสอบให้แน่ใจว่าคุณใช้งานเวอร์ชันนั้นหรือเวอร์ชันที่ใหม่กว่า

บันทึก! คุณสมบัตินี้แสดงURL ดิบดังนั้นจึงไม่ได้รับการถอดรหัสดังที่ระบุไว้ในเอกสารประกอบ:

คุณสมบัตินี้ไม่ได้ใช้ภายในสำหรับการตัดสินใจกำหนดเส้นทางหรือการอนุญาต ยังไม่ได้รับการถอดรหัส URL และควรใช้ความระมัดระวังในการใช้งาน


ฉันใช้ ASP .NET Core กับ. NET Framework แบบเต็ม ดูเหมือนจะไม่ได้ผลสำหรับฉัน ( RawTargetไม่ได้กำหนดไว้IHttpRequestFeature) คุณสามารถคิดหาทางเลือกอื่นได้หรือไม่?
TomášHübelbauer

1
RawTargetถูกเพิ่มเข้ามาใน 1.0 ปล่อยกลับมาในเดือนพฤษภาคม คุณแน่ใจหรือไม่ว่าคุณกำลังใช้งานเวอร์ชันล่าสุด
khellang

1
หากโฮสต์โดยใช้ IIS บางครั้ง IIS จะเปลี่ยน url ก่อนที่จะเข้าสู่ Kestrel ตัวอย่างหนึ่งคือ% 2F ถูกถอดรหัสเป็น /
Daniel Leach

นี่เป็นคำตอบที่เชื่อถือได้
Chris Marisic

ดูเหมือนว่าจะให้เส้นทาง URL แทนที่จะเป็น URL ทั้งหมด
Iain Ballard

12

ใน. NET Core มีดโกน:

@using Microsoft.AspNetCore.Http.Extensions
@Context.Request.GetEncodedUrl() //Use for any purpose (encoded for safe automation)

คุณยังสามารถใช้แทนบรรทัดที่สอง:

@Context.Request.GetDisplayUrl() //Use to display the URL only

9

วิธีแก้ปัญหาอื่น ๆ ไม่เหมาะกับความต้องการของฉันเพราะฉันต้องการURIวัตถุโดยตรงและฉันคิดว่ามันเป็นการดีกว่าที่จะหลีกเลี่ยงการต่อสายอักขระ (ด้วย) ในกรณีนี้ดังนั้นฉันจึงสร้างวิธีการขยายนี้แทนที่จะใช้ a UriBuilderและใช้ได้กับ URL เช่นhttp://localhost:2050:

public static Uri GetUri(this HttpRequest request)
{
    var uriBuilder = new UriBuilder
    {
        Scheme = request.Scheme,
        Host = request.Host.Host,
        Port = request.Host.Port.GetValueOrDefault(80),
        Path = request.Path.ToString(),
        Query = request.QueryString.ToString()
    };
    return uriBuilder.Uri;
}

1
สิ่งที่ดี. นอกจากนี้ฉันยังปรับปรุงโซลูชันของคุณด้วยพารามิเตอร์เสริม ดังนั้นฉันสามารถควบคุมได้ว่าต้องการถอยกลับส่วนใดของ URI ตัวอย่างเช่นโฮสต์เท่านั้นหรือเส้นทางแบบเต็มโดยไม่มีสตริงข้อความค้นหาเป็นต้น
user3172616

@ user3172616 ไอเดียดี!
giammin

1
(80)(-1)ควรจะเป็น เมื่อคุณมี https โครงการที่มีพอร์ตการละเว้นใน "โฮสต์" ส่วนหัวนี้จะสร้างผิด Uri (เช่นhttps://myweb:80/กับ(-1)มันจะเป็นhttps://myweb)
Igor Dražić

4

วิธีการขยายต่อไปนี้จะจำลองตรรกะจาก pre-beta5 UriHelper:

public static string RawUrl(this HttpRequest request) {
    if (string.IsNullOrEmpty(request.Scheme)) {
        throw new InvalidOperationException("Missing Scheme");
    }
    if (!request.Host.HasValue) {
        throw new InvalidOperationException("Missing Host");
    }
    string path = (request.PathBase.HasValue || request.Path.HasValue) ? (request.PathBase + request.Path).ToString() : "/";
    return request.Scheme + "://" + request.Host + path + request.QueryString;
}

3

ส่วนขยายนี้ใช้ได้กับฉัน:

ใช้ Microsoft.AspNetCore.Http;

    public static class HttpRequestExtensions
    {
        public static string GetRawUrl(this HttpRequest request)
        {
            var httpContext = request.HttpContext;
            return $"{httpContext.Request.Scheme}://{httpContext.Request.Host}{httpContext.Request.Path}{httpContext.Request.QueryString}";
        }
    }

0

ใน ASP.NET 5 beta5:

Microsoft.AspNet.Http.Extensions.UriHelper.Encode(
    request.Scheme, request.Host, request.PathBase, request.Path, request.QueryString);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.