Пользовательский System.Web.HttpContext для .Net Standard - PullRequest
0 голосов
/ 10 февраля 2019

У нас есть несколько сайтов, написанных на .Net Framework.Теперь мы хотим перейти на .Net Core.Мы хотим сделать это один за другим, чтобы старые и новые сайты работали бок о бок.Все веб-сайты имеют общие dll, например LoggerDll.

Чтобы использовать только одну dll для обоих веб-сайтов (старых и новых), мы меняем LoggerDll на .Net Standard и добавляем ссылку на него с обоих веб-сайтов.

Проблема в том, что LoggerDll имеет ссылку на System.Web dll для получения IP-адреса запроса (и другой информации о запросе) для записи в журнал, и он не существует в .Net Core.

Например:

public void WriteToLog(string message)
{
    //This line doesn't compile in .Net Core
    string userIp = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
    WriteToDB(message, userIp);
}

Я не хочу передавать IP в качестве параметра в WriteToLog, потому что тогда мне нужно будет добавить его в качестве параметра во ВСЕ методы, которые его вызывают, и почти каждый метод вызываетWriteToLog при возникновении исключения.

Поэтому я предпочитаю продолжать получать информацию запроса от какого-то «глобального» объекта, но он должен компилироваться в .Net Core и .Net Framework.

Я думал о созданииНовый класс, «MyRequestInfo», создайте для него статическое свойство и в событии «BeginRequest» заполните его данными.

Например:

public class MyRequestInfo
{
    public string UserIp { get; set; }
}

public class MyRequest
{
    [ThreadStatic] \\ Is ThreadStatic is ok?
    public static MyRequestInfo ReqInfo { get; set; }
}

//Global.asax
protected void Application_BeginRequest(object sender, EventArgs e)
{
     MyRequest.ReqInfo.UserIp = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
}

//LoggerDll
public void WriteToLog(string message)
{
    string userIp = MyRequest.ReqInfo.UserIp;
    WriteToDB(message, userIp);
}
  1. Isс этим мнением все в порядке?
  2. Правильно ли [ThreadStatic] или я должен использовать AsynLocal или что-то еще?

Спасибо

1 Ответ

0 голосов
/ 12 февраля 2019

Все в порядке?

Ваше решение не будет работать с async/await, поскольку в нем могут участвовать два разных потока, а свойство [ThreadStatic] не будет сохранять значение в асинхронном режиме.течь.

Я должен использовать AsynLocal или что-то еще?

Я не понимаю, как это можно реализовать с помощью AsynLocal.

ВотОсновная идея, как это можно сделать:

LoggerDll

public static Func<string> UserIpGetter;
public void WriteToLog(string message)
{
    string userIp = UserIpGetter();
    WriteToDB(message, userIp);
}

Asp.Net

//Global.asax
static string GetUserIp()
{
    return System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
}
protected void Application_Start(object sender, EventArgs e)
{
     LoggerDll.UserIpGetter = GetUserIp;
}

Asp.Net Core

Startup.cs

public class Startup
{
    static IServiceProvider _serviceProvider;
    static string GetUserIp()
    {
        return _serviceProvider.GetService<IHttpContextAccessor>()
            .HttpContext.Connection.RemoteIpAddress.ToString();
    }
    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddHttpContextAccessor();
        ...
    }
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        _serviceProvider = app.ApplicationServices;
        LoggerDll.UserIpGetter = GetUserIp;
        ...
    }
}

Чтобы улучшить этот код, вы можете объявить: interface IUserIpGetter {string GetUserIp();}, написать одну реализацию в Asp.Net и другую в Asp.Net Core зарегистрируйте их в DI и введите их в LoggerDll.ctor

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...