2014-12-03 1 views
2

Я создаю веб-сервис с веб-контроллером api. Я хочу иметь возможность создать сеанс и проверить состояние сеанса. У меня есть следующие:.NET Web API + Тайм-аут сеанса

Контроллер:

public string Get(string user, string pass) 
{ 
     bool loginValue = false; 
     loginValue = UserNamepassword(user, pass); 

     if (loginValue == true) 
     { 
      HttpContext.Current.Session.Add("Username", user);     
      //session["Username"] = user; 
      //session.Add("Username", user); 
      if ((string)HttpContext.Current.Session["Username"] != null) 
      { 
       HttpContext.Current.Session.Add("Time", DateTime.Now); 

       return "Username: " + (string)HttpContext.Current.Session["Time"] + (string)HttpContext.Current.Session["Username"]; 
      } 
      return "Logged in but session is not availabe for " + (string)HttpContext.Current.Session["Username"]; 
     }    
     else 
      return "Login failed for " + user; 
} 

WebConfig

public static void RegisterRoutes(RouteCollection routes) 
    { 
     var route = routes.MapHttpRoute(
      name: "SessionApi", 
      routeTemplate: "api/{controller}/{user}/{pass}", 
      defaults: new { user = RouteParameter.Optional, pass = RouteParameter.Optional } 
     ); 
     route.RouteHandler = new MyHttpControllerRouteHandler(); 
    } 
    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); 
     } 
    } 

Global.asax.cs

WebApiConfig.RegisterRoutes(RouteTable.Routes); 

Когда я запускаю этот код, я продолжаю получать нулевую ссылку в сессия.

HttpContext.Current.Session.Add("Username", user);     
//session["Username"] = user; 
//session.Add("Username", user); 

Кто-нибудь знает, почему я не могу установить переменную сеанса на что-либо. Неважно, какой метод я использую не из трех, которые работают. Код брал с другого поста.

+1

Не используйте сеанс в веб-Api. Это побеждает цель. – Shyju

+0

Мне нужно. Я не знаю другого пути. Я новичок в веб-API. все еще исследуя это. но на время beng мне нужно использовать его –

+0

Возможный дубликат [сеанса веб-API ASP.NET или что-то?] (http://stackoverflow.com/questions/11478244/asp-net-web-api-session-or- что-то) –

ответ

6

Это дизайн в веб-API, поскольку он предназначен для создания спокойных веб-сервисов. Чтобы быть действительно спокойным, служба не должна иметь никакого состояния, то есть /myserver/somendpoint/5 должен иметь тот же результат для любого запроса с заданным глаголом.

Однако, если это вас не устраивает, вы можете включить сеанс в веб-API, добавив следующее к global.asax.

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

, поэтому, используя тот же код, который у меня есть, просто добавив код, который вы предоставили global.asax, должен работать? –

+0

Да, добавив, что для global.asax вы сможете использовать 'HttpContext.Current.Session [« Независимо от]] и тому подобное. –

+0

Хорошо, что работает. Я получаю «Указанный приказ недействителен». ошибка в этой строке: (строка) HttpContext.Current.Session ["Username"] –

3

Пожалуйста, не надо!

Web API должен быть stateless, RESTful и т.д. С помощью State вы побеждая это вся цель.

+0

Я слышу это во многих постов ... REST должен быть без гражданства. Но использование сеанса мне кажется просто удобством для повышения производительности. например Если мне приходится делать 2 запроса (например, искать пользователя, а затем искать их ресурсы), зачем это делать каждый звонок REST. Почему бы не кэшировать результаты первого поиска, удерживайте их в течение 15 минут в предположении, что люди запрашивают данные в мини-всплесках.Затем выбросьте эти результаты, скажем, 15 минут неиспользования. Как это побеждает всю цель? Как заставить api искать базу данных, делая ее БОЛЕЕ спокойной? – frigon

+0

@frigon, да, кеширование результатов в вашем сценарии полезно. В общем, вы можете сделать это в памяти в рамках одного процесса обработки запроса (не RESTful) или делегировать его другому процессу/серверу (RESTful). Одним из явных преимуществ для использования последнего является масштабируемость: подумайте о ферме серверов, обрабатывающей несколько запросов от одного и того же клиента, если вы используете подход, не относящийся к RESTful. [Вот хороший ответ на эту тему] (http://stackoverflow.com/questions/3105296/if-rest-applications-are-supposed-to-be-stateless-how-do-you-manage-sessions#answer- 3105337), которые могут прояснить ситуацию. – rtorres

6

Здесь семантика часто затуманивает дискуссию. Люди путают объект Session с безгражданством. И часто говорят: «Не используйте сеанс, потому что он не является апатридом!».

Однако они действительно означают, что вы должны стремиться к тому, чтобы ваши спокойные звонки были идемпотентными, то есть они не меняли своего поведения в зависимости от того, что вы делаете в фоновом режиме.

Сессия или кеш-время выполнения или то, что вы используете для кеширования данных, не влияет на ваш дизайн без состояния, потому что на самом деле, что дальше? Ваша база данных тоже имеет смысл? И вы не должны читать данные? Совершенно очевидно; ваше основное хранилище, если оно находится в памяти или на диске, не отражает ваше состояние клиенту.

Так что используйте, конечно, объект сеанса, как указал Бен Робинсон. Но никогда не позволяйте факту, если что-то есть в сеансе IN, возвращают другой результат, тогда когда что-то выходит за сеанс.