简体   繁体   中英

Asp.Net Core 2.x HttpContext.Current not really available

I am not seeing much information on porting a asp.net mvc 4.6 application to the asp.net core 2.1 Tons of 1.0 to 2.0 and 2.0. to 2.1 articles, but it is a bit steep in changes.

Ok, I have been all over google and stackoverflow and what I am trying/wanting to do is convert an older .net application and bring it into .net core.

Some big culprits I see as problems are the following:

HttpContext.Current
HttpContext.Current.Request.Url.AbsolutePath
HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)
private static string CollectionToHtmlTable(HttpCookieCollection collection)

I was seeing these articles which are helpful, but much to be desired.

https://www.carlrippon.com/httpcontext-in-asp-net-core/ https://dotnetcoretutorials.com/2017/01/05/accessing-httpcontext-asp-net-core/

Inside Controller it seems the easiest, but most of this HttpContext.Current stuff is sprinkled around various places domain libraries etc..

So in both url's above it seems that using this line below in the startup.cs however, I don't have a startup.cs outside of main asp.net core

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

Then also in startup I seen this article https://www.strathweb.com/2016/12/accessing-httpcontext-outside-of-framework-components-in-asp-net-core/

//one of many things added to project
services.AddHttpContextAccessor();

I realize that several questions have been asked in the last couple of years - here is to hoping that some brave soul has explored this stuff and has some advise/answers to how to migrate this stuff over.

Method to Port: #1

  public Service(string key, LogRecord.CallType callType, string operation, string opArg, string opResponse)
    {
        this.Key = string.IsNullOrEmpty(key)
                       ? HttpContext.Current != null ? "Inbound/WebHttp: " + HttpContext.Current.Request.Url.AbsolutePath : string.Empty
                       : key;
        this.CallType = Enum.GetName(typeof(LogRecord.CallType), callType);
        this.URL = HttpContext.Current != null && callType == LogRecord.CallType.WebHttp
                       ? HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)
                       : string.Empty;
        this.Operation = operation;
        this.OpArg = opArg;
        this.OpResponse = opResponse;
    }

Another: #2

   private static string CollectionToHtmlTable(HttpCookieCollection collection)
    {
        // Converts HttpCookieCollection to NameValueCollection
        var nvc = new NameValueCollection();
        foreach (string item in collection)
        {
            var httpCookie = collection[item];
            if (httpCookie != null)
            {
                nvc.Add(item, httpCookie.Value);
            }
        }

        return CollectionToHtmlTable(nvc);
    }

The problem is, you are currently using it wrong.

Inside Controller it seems the easiest, but most of this HttpContext.Current stuff is sprinkled around various places domain libraries etc..

A Domain Libarary should be independent from the frontend. It just doesn't matter if it's a website with Session or a statefull WPF App. Or a RestFull Api.

That said, a relative Quick Fix would be to inject the HttpContext into your domain class.

public DomainService(IHttpContextAccessor httpContext)
{
    _httpContext = httpContext;
}

You can then obtain your DomainService via Dependency Injection. If the creation is complex, you are looking for a Factory .

Or you could create the Service yourself in your ActionMethod (Of course in this case you need need to change the constructor of the Service to HttpContext:

public IActionResult Foo()
{
    var service = new DomainService(HttpContext)
}

That said: it was removed for a reason. Please do not rely on HttpContext in your Domain! Create a business object and give it as parameter to the domain instead.


Not sure if it is the best way, but I have created a BusinessContext class and registered it as scoped. A factory is responsible for creating it with the needed data.


DON'T DO THIS:

If you are really crazy, maybe this could help you for migration.

Posting this on request of OP, so it's not a full answer. You can reconstruct the URI from the IHttpContextAccessor like so:

IHttpContextAccessor context; // injected
var request = context.HttpContext.Request;

var uriBuilder = new UriBuilder();
uriBuilder.Scheme = request.Scheme;
uriBuilder.Host = request.Host.Host;
if (request.Host.Port.HasValue)
{
    uriBuilder.Port = request.Host.Port.Value;
}
uriBuilder.Path = request.Path;
if (request.QueryString.HasValue)
{
    uriBuilder.Query = request.QueryString.Value.Substring(1);
}

var requestUri = uriBuilder.Uri;

Likewise, you can access the IRequestCookieCollection via:

var collection = context.HttpContext.Request.Cookies
foreach (KeyValuePair<string, string> cookie in collection)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM