ASP.NET कोर का उपयोग करके पूर्ण URL प्राप्त करना


82

MVC 5 में, मेरे पास संबंधित URL के बजाय पूर्ण URL बनाने के लिए निम्नलिखित एक्सटेंशन विधियाँ थीं:

public static class UrlHelperExtensions
{
    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);
    }

    public static string AbsoluteContent(
        this UrlHelper url,
        string contentPath)
    {
        return new Uri(url.RequestContext.HttpContext.Request.Url, url.Content(contentPath)).ToString();
    }

    public static string AbsoluteRouteUrl(
        this UrlHelper url,
        string routeName,
        object routeValues = null)
    {
        string scheme = url.RequestContext.HttpContext.Request.Url.Scheme;
        return url.RouteUrl(routeName, routeValues, scheme);
    }
}

ASP.NET कोर में समकक्ष क्या होगा?

  • UrlHelper.RequestContext अब मौजूद नहीं है।
  • आप नहीं पकड़ सकते हैं HttpContextक्योंकि अब कोई स्थिर HttpContext.Currentसंपत्ति नहीं है।

जहां तक ​​मैं देख सकता हूं, अब आपको HttpContextया HttpRequestवस्तुओं को भी इसमें पारित करने की आवश्यकता होगी । क्या मैं सही हू? क्या वर्तमान अनुरोध को पकड़ पाने का कोई तरीका है?

क्या मैं यहां तक ​​कि सही रास्ते पर हूं, क्या डोमेन को अब एक पर्यावरण चर होना चाहिए, जो सापेक्ष URL के लिए सरल है? क्या यह एक बेहतर दृष्टिकोण होगा?


1
पूर्ण URL प्राप्त करना क्या है?
im1dermike

@ im1dermike उदाhttp://example.com/controller/action
मुहम्मद रेहान सईद

जवाबों:


74

RC2 और 1.0 के बादIHttpContextAccessor आपको एक्सटेंशन क्लास में इंजेक्ट करने की आवश्यकता नहीं है । इसके IUrlHelperमाध्यम से तुरंत उपलब्ध है urlhelper.ActionContext.HttpContext.Request। फिर आप एक ही विचार के बाद एक विस्तार वर्ग का निर्माण करेंगे, लेकिन इसमें कोई इंजेक्शन शामिल नहीं होगा।

public static string AbsoluteAction(
    this IUrlHelper url,
    string actionName, 
    string controllerName, 
    object routeValues = null)
{
    string scheme = url.ActionContext.HttpContext.Request.Scheme;
    return url.Action(actionName, controllerName, routeValues, scheme);
}

किसी व्यक्ति के लिए उपयोगी होने के मामले में विवरण का निर्माण करना कि यह एक्सीसर को कैसे इंजेक्ट करता है। आपको वर्तमान अनुरोध के पूर्ण यूआरएल में भी दिलचस्पी हो सकती है, जिस स्थिति में उत्तर के अंत में एक नज़र डालें।


आप IHttpContextAccessorइंटरफ़ेस प्राप्त करने के लिए इंटरफ़ेस का उपयोग करने के लिए अपनी एक्सटेंशन क्लास को संशोधित कर सकते हैं HttpContext। एक बार जब आप संदर्भ है, तो आप प्राप्त कर सकते हैं HttpRequestसे उदाहरण HttpContext.Requestऔर उसके गुणों का उपयोग Scheme, Host, Protocolके रूप में आदि:

string scheme = HttpContextAccessor.HttpContext.Request.Scheme;

उदाहरण के लिए, आपको अपने वर्ग को HttpContextAccessor से कॉन्फ़िगर करने की आवश्यकता हो सकती है:

public static class UrlHelperExtensions
{        
    private static IHttpContextAccessor HttpContextAccessor;
    public static void Configure(IHttpContextAccessor httpContextAccessor)
    {           
        HttpContextAccessor = httpContextAccessor;  
    }

    public static string AbsoluteAction(
        this IUrlHelper url,
        string actionName, 
        string controllerName, 
        object routeValues = null)
    {
        string scheme = HttpContextAccessor.HttpContext.Request.Scheme;
        return url.Action(actionName, controllerName, routeValues, scheme);
    }

    ....
}

जो कुछ आप अपनी Startupकक्षा (Startup.cs फ़ाइल) पर कर सकते हैं :

public void Configure(IApplicationBuilder app)
{
    ...

    var httpContextAccessor = app.ApplicationServices.GetRequiredService<IHttpContextAccessor>();
    UrlHelperExtensions.Configure(httpContextAccessor);

    ...
}

आप शायद IHttpContextAccessorअपने विस्तार वर्ग में आने के विभिन्न तरीकों के साथ आ सकते हैं , लेकिन यदि आप अपने तरीकों को अंत में विस्तार विधियों के रूप में रखना चाहते हैं, तो आपको IHttpContextAccessorअपने स्थिर वर्ग में इंजेक्शन लगाने की आवश्यकता होगी । (अन्यथा आपको IHttpContextप्रत्येक कॉल पर तर्क के रूप में आवश्यकता होगी )


बस वर्तमान अनुरोध के निरपेक्षता हो रही है

यदि आप वर्तमान अनुरोध के पूर्ण uri प्राप्त करना चाहते हैं, तो आप विस्तार विधियों GetDisplayUrlया वर्ग GetEncodedUrlसे उपयोग कर सकते हैं UriHelper। (जो उर एल हेल्पर से अलग है )

GetDisplayUrl । अनुरोध URL के संयुक्त घटकों को पूरी तरह से अन-एस्केप किए गए फ़ॉर्म में (क्वेरीरी छोड़कर) केवल प्रदर्शन के लिए उपयुक्त है। इस प्रारूप का उपयोग HTTP हेडर या अन्य HTTP संचालन में नहीं किया जाना चाहिए।

GetEncodedUrl । HTTP हेडर और अन्य HTTP ऑपरेशन में उपयोग के लिए पूरी तरह से बच गए फॉर्म में अनुरोध URL के संयुक्त घटकों को लौटाता है।

उनका उपयोग करने के लिए:

  • नाम स्थान शामिल करें Microsoft.AspNet.Http.Extensions
  • HttpContextउदाहरण प्राप्त करें । यह पहले से ही कुछ वर्गों में उपलब्ध है (जैसे कि उस्तरा विचार), लेकिन दूसरों में आपको IHttpContextAccessorऊपर बताए अनुसार इंजेक्शन लगाने की आवश्यकता हो सकती है।
  • तो बस उन्हें के रूप में उपयोग करें this.Context.Request.GetDisplayUrl()

उन तरीकों के लिए एक विकल्प मैन्युअल रूप से HttpContext.Requestवस्तु में मूल्यों का उपयोग करके अपने आप को पूर्ण यूरी क्राफ्टिंग करना होगा (इसी तरह की आवश्यकता है।

var absoluteUri = string.Concat(
                        request.Scheme,
                        "://",
                        request.Host.ToUriComponent(),
                        request.PathBase.ToUriComponent(),
                        request.Path.ToUriComponent(),
                        request.QueryString.ToUriComponent());

हमें अब UrlHelper के बजाय IUrlHelper का उपयोग करना चाहिए। सभी वस्तुएं MVC 6 में बहुत अधिक डिस्कनेक्ट हैं। मुझे लगता है कि आपका विकल्प सबसे अच्छा है।
मुहम्मद रेहान सईद

RC1 के साथ काम नहीं करता है। एक्सटेंशन विधि के साथ रनटाइम त्रुटि देखें। इसके अलावा, UriHelperलिंक मर चुका है।
मृकफ

2
@ मैक्रिफ़ मैंने लिंक को अपडेट कर दिया है (RC2 के लिए नाम स्थान बदल गए हैं, इसलिए देव शाखा के सभी लिंक समाप्त हो गए हैं ...)। हालाँकि, मैंने अभी एक RC1 प्रोजेक्ट बनाया है, @using Microsoft.AspNet.Http.Extensionsजो Index.cshtml व्यू में जोड़ा गया है और उन एक्सटेंशन का उपयोग करने में सक्षम है जैसे@Context.Request.GetDisplayUrl()
डैनियल जेजी

44

ASP.NET कोर 1.0 के लिए आगे

/// <summary>
/// <see cref="IUrlHelper"/> extension methods.
/// </summary>
public static class UrlHelperExtensions
{
    /// <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 IUrlHelper url,
        string actionName,
        string controllerName,
        object routeValues = null)
    {
        return url.Action(actionName, controllerName, routeValues, url.ActionContext.HttpContext.Request.Scheme);
    }

    /// <summary>
    /// Generates a fully qualified URL to the specified content by using the specified content path. Converts a
    /// virtual (relative) path to an application absolute path.
    /// </summary>
    /// <param name="url">The URL helper.</param>
    /// <param name="contentPath">The content path.</param>
    /// <returns>The absolute URL.</returns>
    public static string AbsoluteContent(
        this IUrlHelper url,
        string contentPath)
    {
        HttpRequest request = url.ActionContext.HttpContext.Request;
        return new Uri(new Uri(request.Scheme + "://" + request.Host.Value), url.Content(contentPath)).ToString();
    }

    /// <summary>
    /// Generates a fully qualified URL to the specified route by using the route name and route values.
    /// </summary>
    /// <param name="url">The URL helper.</param>
    /// <param name="routeName">Name of the route.</param>
    /// <param name="routeValues">The route values.</param>
    /// <returns>The absolute URL.</returns>
    public static string AbsoluteRouteUrl(
        this IUrlHelper url,
        string routeName,
        object routeValues = null)
    {
        return url.RouteUrl(routeName, routeValues, url.ActionContext.HttpContext.Request.Scheme);
    }
}

बोनस टिप

आप सीधे IUrlHelperDI कंटेनर में पंजीकरण नहीं कर सकते । IUrlHelperका उपयोग करने के लिए आप की आवश्यकता का एक उदाहरण को हल करने IUrlHelperFactoryऔर IActionContextAccessor। हालाँकि, आप शॉर्टकट के रूप में निम्न कार्य कर सकते हैं:

services
    .AddSingleton<IActionContextAccessor, ActionContextAccessor>()
    .AddScoped<IUrlHelper>(x => x
        .GetRequiredService<IUrlHelperFactory>()
        .GetUrlHelper(x.GetRequiredService<IActionContextAccessor>().ActionContext));

ASP.NET कोर बैकलॉग

अद्यतन : यह ASP.NET कोर 5 नहीं बनाएगा

ऐसे संकेत हैं कि आप LinkGeneratorनिरपेक्ष URL बनाने के लिए उपयोग करने में सक्षम होंगे, HttpContextयह प्रदान करने की आवश्यकता के बिना (यह सबसे बड़ा नकारात्मक पहलू था LinkGeneratorऔर क्यों IUrlHelperनीचे दिए गए समाधान का उपयोग करके सेटअप करने के लिए अधिक जटिल था, उपयोग करना आसान था) देखें "कॉन्फ़िगर करना आसान बनाएं LinkGenerator के साथ निरपेक्ष यूआरएल के लिए एक मेजबान / योजना "


1
कि मुझे क्या चाहिए? देखें stackoverflow.com/q/37928214/153923
jp2code

4
यह ठीक है, लेकिन यह मुझे लगता है कि कुछ सरल के लिए बहुत अधिक कोड है। क्या हम सिर्फ साथ रह सकते हैंstring url = string.Concat(this.Request.Scheme, "://", this.Request.Host, this.Request.Path, this.Request.QueryString);
जूनियर मय

19

इसके लिए आपको कोई एक्सटेंशन विधि बनाने की आवश्यकता नहीं है

@Url.Action("Action", "Controller", values: null);

  • Action - कार्रवाई का नाम
  • Controller - नियंत्रक का नाम
  • values - रूट वैल्यू युक्त ऑब्जेक्ट: उर्फ ​​गेट पैरामीटर

लिंक उत्पन्न करने के लिएUrl.Action आपके द्वारा उपयोग किए जाने वाले बहुत सारे अन्य ओवरलोड भी हैं ।


1
धन्यवाद! यह वही था जो मुझे चाहिए था, लेकिन मुझे समझ नहीं आया कि क्या है this.Context.Request.Scheme। क्या केवल URL के प्रोटोकॉल और डोमेन हिस्से मिलते हैं?
लुकास

this.Context.Request.Schemaअनुरोध के लिए उपयोग किया गया प्रोटोकॉल लौटाता है। यह उन सभी लोगों httpया https। यहाँ डॉक्स हैं, लेकिन यह वास्तव में यह नहीं बताता है कि स्कीमा का मतलब क्या है।
केली एल्टन

14

यदि आप केवल एक विधि के लिए एक उरी चाहते हैं जिसमें एक मार्ग एनोटेशन है, तो निम्नलिखित ने मेरे लिए काम किया।

कदम

रिलेटिव URL प्राप्त करें

लक्ष्य कार्रवाई के रूट नाम को नोट करते हुए, निम्न के रूप में नियंत्रक की URL संपत्ति का उपयोग करके संबंधित URL प्राप्त करें :

var routeUrl = Url.RouteUrl("*Route Name Here*", new { *Route parameters here* });

एक पूर्ण URL बनाएँ

var absUrl = string.Format("{0}://{1}{2}", Request.Scheme,
            Request.Host, routeUrl);

एक नई उड़ी बनाएं

var uri = new Uri(absUrl, UriKind.Absolute)

उदाहरण

[Produces("application/json")]
[Route("api/Children")]
public class ChildrenController : Controller
{
    private readonly ApplicationDbContext _context;

    public ChildrenController(ApplicationDbContext context)
    {
        _context = context;
    }

    // GET: api/Children
    [HttpGet]
    public IEnumerable<Child> GetChild()
    {
        return _context.Child;
    }

    [HttpGet("uris")]
    public IEnumerable<Uri> GetChildUris()
    {
        return from c in _context.Child
               select
                   new Uri(
                       $"{Request.Scheme}://{Request.Host}{Url.RouteUrl("GetChildRoute", new { id = c.ChildId })}",
                       UriKind.Absolute);
    }


    // GET: api/Children/5
    [HttpGet("{id}", Name = "GetChildRoute")]
    public IActionResult GetChild([FromRoute] int id)
    {
        if (!ModelState.IsValid)
        {
            return HttpBadRequest(ModelState);
        }

        Child child = _context.Child.Single(m => m.ChildId == id);

        if (child == null)
        {
            return HttpNotFound();
        }

        return Ok(child);
    }
}

9

यह मुहम्मद रेहान सईद द्वारा अन्वेषक की भिन्नता है , वर्ग को उसी नाम के मौजूदा .net कोर MVC वर्ग से परजीवी रूप से जुड़ा हुआ है, ताकि सब कुछ बस काम करे।

namespace Microsoft.AspNetCore.Mvc
{
    /// <summary>
    /// <see cref="IUrlHelper"/> extension methods.
    /// </summary>
    public static partial class UrlHelperExtensions
    {
        /// <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 IUrlHelper url,
            string actionName,
            string controllerName,
            object routeValues = null)
        {
            return url.Action(actionName, controllerName, routeValues, url.ActionContext.HttpContext.Request.Scheme);
        }

        /// <summary>
        /// Generates a fully qualified URL to the specified content by using the specified content path. Converts a
        /// virtual (relative) path to an application absolute path.
        /// </summary>
        /// <param name="url">The URL helper.</param>
        /// <param name="contentPath">The content path.</param>
        /// <returns>The absolute URL.</returns>
        public static string AbsoluteContent(
            this IUrlHelper url,
            string contentPath)
        {
            HttpRequest request = url.ActionContext.HttpContext.Request;
            return new Uri(new Uri(request.Scheme + "://" + request.Host.Value), url.Content(contentPath)).ToString();
        }

        /// <summary>
        /// Generates a fully qualified URL to the specified route by using the route name and route values.
        /// </summary>
        /// <param name="url">The URL helper.</param>
        /// <param name="routeName">Name of the route.</param>
        /// <param name="routeValues">The route values.</param>
        /// <returns>The absolute URL.</returns>
        public static string AbsoluteRouteUrl(
            this IUrlHelper url,
            string routeName,
            object routeValues = null)
        {
            return url.RouteUrl(routeName, routeValues, url.ActionContext.HttpContext.Request.Scheme);
        }
    }
}

5

मुझे अभी पता चला है कि आप इसे इस कॉल के साथ कर सकते हैं:

Url.Action(new UrlActionContext
{
    Protocol = Request.Scheme,
    Host = Request.Host.Value,
    Action = "Action"
})

यह योजना, होस्ट, पोर्ट, सब कुछ बनाए रखेगा।


3

नियंत्रक क्रिया में एक नए ASP.Net 5 MVC प्रोजेक्ट में आप अभी भी कर सकते हैं this.Contextऔर this.Context.Requestऐसा लगता है कि अनुरोध पर अब कोई Url संपत्ति नहीं है, लेकिन बच्चे के गुण (स्कीमा, होस्ट, आदि) सभी सीधे अनुरोध ऑब्जेक्ट पर हैं।

 public IActionResult About()
    {
        ViewBag.Message = "Your application description page.";
        var schema = this.Context.Request.Scheme;

        return View();
    }

इसके बजाय या आप इसका उपयोग नहीं करना चाहते हैं। कॉन्टेक्स्ट या संपत्ति को इंजेक्ट करना एक और बातचीत है। ASP.NET vNext में निर्भरता इंजेक्शन


3

यदि आप केवल वैकल्पिक मापदंडों के साथ एक सापेक्ष पथ को परिवर्तित करना चाहते हैं तो मैंने IHttpContextAccessor के लिए एक एक्सटेंशन विधि बनाई

public static string AbsoluteUrl(this IHttpContextAccessor httpContextAccessor, string relativeUrl, object parameters = null)
{
    var request = httpContextAccessor.HttpContext.Request;

    var url = new Uri(new Uri($"{request.Scheme}://{request.Host.Value}"), relativeUrl).ToString();

    if (parameters != null)
    {
        url = Microsoft.AspNetCore.WebUtilities.QueryHelpers.AddQueryString(url, ToDictionary(parameters));
    }

    return url;
}


private static Dictionary<string, string> ToDictionary(object obj)
{
    var json = JsonConvert.SerializeObject(obj);
    return JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
}

तब आप अपनी सेवा से विधि को कॉल कर सकते हैं / इंजेक्शन IHttpContextAccessor का उपयोग कर सकते हैं

var callbackUrl = _httpContextAccessor.AbsoluteUrl("/Identity/Account/ConfirmEmail", new { userId = applicationUser.Id, code });

2

आप इस तरह यूआरएल प्राप्त कर सकते हैं:

Request.Headers["Referer"]

व्याख्या

Request.UrlRefererएक फेंक होगा System.UriFormatExceptionयदि संदर्भित HTTP हेडर विकृत है (जो भी हो सकता है, क्योंकि यह आम तौर पर आपके नियंत्रण में नहीं है)।

प्रयोग करने के लिए के रूप में Request.ServerVariables, MSDN प्रति :

Request.ServerVariables संग्रह

ServerVariables संग्रह पूर्वनिर्धारित परिवेश चर के मानों को पुनः प्राप्त करता है और शीर्ष लेख की जानकारी का अनुरोध करता है।

अनुरोध

HTTP हेडर का एक संग्रह हो जाता है।

मुझे लगता है मुझे समझ में नहीं आता है कि आप Request.ServerVariablesओवर को क्यों पसंद करेंगे Request.Headers, क्योंकि Request.ServerVariablesइसमें सभी पर्यावरण चर और हेडर शामिल हैं, जहां Request.Headers एक बहुत छोटी सूची है जिसमें केवल हेडर शामिल हैं।

तो सबसे अच्छा समाधान Request.Headersमूल्य को सीधे पढ़ने के लिए संग्रह का उपयोग करना है । HTML के बारे में Microsoft की चेतावनियों को ध्यान में रखें यदि आप इसे एक फॉर्म पर प्रदर्शित करने जा रहे हैं, तो मान को एन्कोडिंग करें।


संदर्भ विश्वसनीय नहीं है, ब्राउज़रों को इसे भेजने के लिए मजबूर नहीं किया जाता है। दूसरे शब्दों में, उपयोगकर्ता सुरक्षा उपायों के रूप में, संदर्भकर्ता को नहीं भेजने के लिए अपने ब्राउज़र को कॉन्फ़िगर कर सकते हैं।
11
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.