【问题标题】:Asp.Net Core 2.x HttpContext.Current not really availableAsp.Net Core 2.x HttpContext.Current 不可用
【发布时间】:2018-08-07 00:10:55
【问题描述】:

我没有看到太多关于将 asp.net mvc 4.6 应用程序移植到 1.0 到 2.0 和 2.0 的 asp.net core 2.1 的信息。到2.1的文章,但是变化有点大。

好的,我一直在使用 google 和 stackoverflow,而我正在尝试/想要做的是将旧的 .net 应用程序转换为 .net 核心。

我认为问题的一些大罪魁祸首如下:

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

我看到这些文章很有帮助,但还有很多不足之处。

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

在 Controller 中它似乎是最简单的,但是大部分 HttpContext.Current 的东西散布在各个地方的域库等。

所以在上面的两个网址中,似乎在startup.cs 中使用下面的这一行 但是,我在主 asp.net 核心之外没有 startup.cs

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

然后在启动时我也看到了这篇文章 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();

我意识到在过去的几年中已经提出了几个问题 - 希望一些勇敢的灵魂已经探索了这些东西,并对如何迁移这些东西有一些建议/答案。

端口方法:#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;
    }

另一个:#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);
    }

【问题讨论】:

  • 不太清楚你在问什么。你想在其他项目的类中注入HttpContextAccessor 吗?请注意,HttpContext.Current 已被弃用,因为它被广泛滥用,所以你应该问自己是否真的需要它
  • “但是,我在主 asp.net 核心之外没有 startup.cs” - 这不是您要找的吗?您在使用 IHttpContextAccessor 和(可能)IActionContextAcccessor 时遇到了什么问题?
  • @CamiloTerevinto 如果我想移植一个应用程序——我粘贴的这些 url 中的这些黑客,尤其是 Strathweb 的,没有请求。路径——需要基于以前开发人员编写的所有代码用于服务、安全、错误日志身份等。
  • @john - 在 asp.net 中只有一个 startup.cs 文件 - 但是我希望在无法使用上述方法的类库中。希望基本上得到移植
  • 你目前是否使用依赖注入?

标签: c# asp.net-core


【解决方案1】:

问题是,你现在用错了。

在 Controller 内部似乎是最简单的,但是大部分 HttpContext.Current 东西散布在各个地方的域库等。

域库应该独立于前端。它是带有 Session 的网站还是有状态的 WPF 应用程序都没有关系。或 RestFull Api。

也就是说,相对快速修复是将inject HttpContext 放入您的域类中。

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

然后您可以通过依赖注入获取您的 DomainService。如果创建复杂,您正在寻找Factory

或者你可以在你的ActionMethod中自己创建Service(当然在这种情况下你需要将Service的构造函数改为HttpContext:

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

也就是说:它被删除是有原因的。请不要在您的域中依赖 HttpContext!创建一个业务对象并将其作为参数提供给域。


不确定这是否是最好的方法,但我创建了一个 BusinessContext 类并将其注册为作用域。工厂负责使用所需数据创建它。


不要这样做:

如果你真的很疯狂,也许this 可以帮助你迁移。

【讨论】:

  • “请不要在你的域中依赖 HttpContext”。就我而言,我想为每个数据库调用添加一个 IP 地址,这有什么问题?我需要在每个控制器上收集 IP 地址吗?
  • 我的意思是,不要直接依赖它。如果您需要域中的 IP 地址,请创建一个可以传输 IP 地址的服务(例如,IBusinessContextIpAdress {get;}。当您拥有一个网站时,工厂会根据您的环境(例如 HttpContext)创建它。这使您可以使用 WPF 应用程序中的相同域,其中 IP 是从 HttpContext 以外的其他东西创建的。@Toolkit
【解决方案2】:

应 OP 的要求发布此内容,因此这不是一个完整的答案。您可以像这样从 IHttpContextAccessor 重建 URI:

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;

同样,您可以通过以下方式访问IRequestCookieCollection

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

【讨论】:

  • 我认为 // injected 部分是造成 OP 最大问题的原因。我很确定他们认为他们无法访问 asp.net 核心项目之外的 DI 容器
  • @Camilio 我确实尝试用评论来探讨这个问题,但在这方面没有得到回复。如有需要会更新一点。
猜你喜欢
  • 2020-08-21
  • 2016-11-28
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 2018-06-08
  • 1970-01-01
相关资源
最近更新 更多