Вопрос по asp.net-web-api, session – ASP.NET Web API сеанс или что-то?

59

Мне нужно хранить некоторую информацию в сеансе (или в любом другом месте в ASP.NET Web API), которую мне нужно получать при каждом запросе API. У нас будет один веб-сайт API IIS, и через заголовок узла будет добавлено несколько привязок веб-сайта. Например, при поступлении любого запроса, api.xyz.com, будет проверяться заголовок хоста, и информация этого веб-сайта будет храниться в сеансе, который будет использоваться при каждом последующем запросе API при вызове базы данных.

Я знаю, что нет поддержки сеанса в ASP.NET Web API. Есть ли другой способ справиться с такой ситуацией? Где я могу хранить информацию, которую можно получить в каждом последующем запросе?

Благодарю.

Ваш Ответ

5   ответов
1

как описано здесь.

Пакет Microsoft.AspNetCore.Session предоставляет промежуточное программное обеспечение для управления состоянием сеанса.

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
  // Adds a default in-memory implementation of IDistributedCache.
    services.AddDistributedMemoryCache();

    services.AddSession(options =>
    {
        // Set a short timeout for easy testing.
        options.IdleTimeout = TimeSpan.FromSeconds(10);
        options.Cookie.HttpOnly = true;
    });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseSession();
}

Из документов: Введение в сессию и состояние приложения в ASP.NET Core

Уже проверено на работающем проекте

Это ответ только для ссылки. Пожалуйста, добавьте (по крайней мере) основные части ссылки, которую вы предоставляете.
25

В WebApi 2 вы можете добавить это вglobal.asax

protected void Application_PostAuthorizeRequest() 
{
    System.Web.HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
}

Тогда вы можете получить доступ к сессии через:

HttpContext.Current.Session
Как это добавляет что-либо к другим ответам?
Это правильный ответ. Большое спасибо ..
@eddie_cat, проще говоря, он помещает это в PostAuthorize. Тем не менее, чтобы сделать это лучше, он мог бы указать на это и добавить условную проверку, если запрос является запросом API, как указывает Nima.
82

REST по замыслу не имеет гражданства. Добавляя сессию (или что-либо еще в этом роде), вы делаете ее состоящей из состояний и побеждаете любую цель иметь RESTful API.

Вся идея сервиса RESTful заключается в том, чтоevery resource is uniquely addressable using a universal syntax for use in hypermedia links а такжеeach HTTP request should carry enough information by itself for its recipient to process it to be in complete harmony with the stateless nature of HTTP".

Поэтому все, что вы пытаетесь сделать с Web API здесь, скорее всего, следует реструктурировать, если вы хотите иметь RESTful API.

С учетом вышесказанного, если вы все еще хотите пойти по этому пути, существует хакерский способ добавления сеанса в Web API, и Имран разместил его здесьhttp://forums.asp.net/t/1780385.aspx/1

Код (хотя я бы не рекомендовал это):

public class MyHttpControllerHandler
  : HttpControllerHandler, IRequiresSessionState
{
    public MyHttpControllerHandler(RouteData routeData): base(routeData)
    { }
}

public class MyHttpControllerRouteHandler : HttpControllerRouteHandler
{
    protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        return new MyHttpControllerHandler(requestContext.RouteData);
    }
}

public class ValuesController : ApiController
{
   public string GET(string input)
   {
       var session = HttpContext.Current.Session;
       if (session != null)
       {
           if (session["Time"] == null)
           {
               session["Time"] = DateTime.Now;
           }
           return "Session Time: " + session["Time"] + input;
       }
       return "Session is not availabe" + input;
    }
}

и затем добавьте HttpControllerHandler в ваш маршрут API:

route.RouteHandler = new MyHttpControllerRouteHandler();
Контроллер будет сложным для модульного тестирования таким образом. Я бы добавил аргумент HttpContextBase (или HttpSessionStateBase) в конструктор контроллера и использовал DI для его разрешения в новом HttpContextWrapper (HttpContext.Current) для приложения. Затем в модульных тестах вы можете поиздеваться над этим.
что насчет кеша?
Я считаю, что контроллеры Web Api очень полезны тем, что я могу установить модель или модель представления в качестве возвращаемого типа, и это прекрасно работает с моими средами javascript, поэтому мне не нужно создавать JsonResults в обычных контроллерах. В этом смысле они не являются истинными контроллерами API REST без сохранения состояния, но являются более естественной конечной точкой для запросов AJAX, и поэтому состояние сеанса все еще является тем, что я хотел бы иметь.
Как сказал @Filip, давайте не будем следовать по этому пути (добавляя сеанс к веб-API, который, как предполагается, не имеет состояния). Но у того же Филипа есть хорошая статья о кешировании веб-API:goo.gl/2rnfI  Я разветвлял его в gitHub и добавил несколько дополнительных функций в исходный код, теперь он поддерживает отдельный кэш вывода для зарегистрированных пользователей:goo.gl/oW4hX ПРИМЕЧАНИЕ. Я все еще совершенствую код и проверяю его на предмет любых возможных нарушений безопасности.
Благодарю. очень полезно. Я не иду против REST, но я хотел сохранить поездку базы данных для каждого запроса API. У нас есть уникальный идентификатор, связанный с доменом API, который делает запрос, который мне нужно передать в вызов базы данных для каждого запроса API. Если я не использую сессию, я повторяю одну и ту же логику для каждого запроса API. Кстати, есть ли способ, которым я могу переопределить аналогично PreRequestHandlerExecute у нас в asp.net и хранить данные в сеансе, которые я хочу получить в каждом запросе API? user1186065
3

если данные достаточно малы и не представляют проблемы безопасности. Тот же подход на основе HttpContext.Current должен работать.

HTTP-заголовки запроса и ответа также могут использоваться для передачи информации между вызовами службы.

Я знаю, что это старо, но может помочь любому, кто читает об этом материале. Существует ограничение на использование файлов cookie с IE8 / 9, если вы используете XDomainRequest для выполнения запросов AJAX CORS. Вы можете прочитать больше об этомhere
93

public override void Init()
{
    this.PostAuthenticateRequest += MvcApplication_PostAuthenticateRequest;
    base.Init();
}

void MvcApplication_PostAuthenticateRequest(object sender, EventArgs e)
{
    System.Web.HttpContext.Current.SetSessionStateBehavior(
        SessionStateBehavior.Required);
}

дать ему шанс ;)

Это сработало! Большое спасибо! Верхний ответ не сработал, так как route.RouteHandler, похоже, не работает, потому что это не тот же тип в Web API. Этот ответ решил проблему.
Я использовал это, и некоторые из моих страниц стали очень медленными. Лучше проверить, является ли запрос веб-API: if (HttpContext.Current.Request.Url.AbsolutePath.StartsWith (& quot; / api / & quot;))
@nima есть несколько лишних символов в [..] (& quot; / api & quot;)) вашего комментария: & amp; zwnj; & amp; # 8203;
+1 Я думаю, что можно использовать Session в Web Api в некоторых особых случаях, если вы знаете, что делаете.
Как установить тайм-аут сеанса для этого?

Похожие вопросы