2012-07-13 6 views
48

すべてのAPIリクエストで取得する必要のある情報をセッション(またはASP.NET Web APIのどの項目でも)に保存する必要があります。私たちは1つのapi IIS Webサイトを持ち、複数のWebサイトのバインディングがホストヘッダーを通じて追加されます。たとえばapi.xyz.comなどのリクエストがあると、ホストヘッダーがチェックされ、そのWebサイト情報がセッションに格納されます。この情報は、データベースへの呼び出し時に後続の各apiリクエストで使用されます。ASP.NET Web APIセッションまたは何か?

私はASP.NET Web APIでセッションのサポートがないことを知っています。このような状況に対処する他の方法はありますか?後続のリクエストごとに取得できる情報はどこに保存できますか?

ありがとうございました。

答えて

69

まあ、デザインによるRESTはステートレスです。セッション(またはその種のもの)を追加することで、ステートフルになり、RESTful APIを持つ目的を破ります。

RESTfulなサービスの全体的なアイデアは、すべてのリソースは、各HTTPリクエストは完全に調和にあると、それを処理するために、その受取人のために、それ自体で十分な情報を伝える必要がありハイパーメディアリンクで使用するための汎用構文を使用して一意にアドレス指定可能であるということですですから、ここでのWeb APIをどうしようとしているものは何でも

。HTTP」のステートレスな性質を持つ、最も可能性の高い再アーキテクチャ・べきであるあなたがRESTfulなAPIを持っているしたい場合。

ということで、もしあなたはまだそのルートを下りたいと思っています。seを追加するためのハッキーな方法があります

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; 
    } 
} 

をして、あなたのAPIのルートにHttpControllerHandlerを追加します:ウェブAPIへssion、そしてそれはイムランによって投稿されていますが、ここでhttp://forums.asp.net/t/1780385.aspx/1

コードは(私は実際にそれをお勧めしませんが)

route.RouteHandler = new MyHttpControllerRouteHandler(); 
+0

感謝をテストしました。非常に役立ちます。私はRESTに反対していませんが、私は各apiの要求に対してデータベースのトリップを保存したかったのです。私たちは、apiドメインに関連付けられた一意のidを持っています。これは、各apiリクエストのデータベース呼び出しに渡す必要があるリクエストです。私がセッションを使用しない場合、私はそれぞれのAPIリクエストに対して同じロジックを繰り返すことになります。 BTWには私がasp.netで持っているPreRequestHandlerExecuteに似たオーバーライドができ、各apiリクエストで取得したいセッションのデータを格納する方法がありますか? – user1186065

+4

コントローラはこのように単体テストを行うのが難しくなります。コントローラコンストラクタでHttpContextBase(またはHttpSessionStateBase)引数を追加し、DIを使用してアプリケーションの新しいHttpContextWrapper(HttpContext.Current)に解決します。ユニットテストでは、それを嘲笑することができます。 –

+0

@Filipが言っているように、このパスに従わないでください(ステートレスであるはずのWeb APIにセッションを追加する)。しかし、同じFilipはWeb API Cachingについての良い記事を持っています:http://goo.gl/2rnfI 私はgitHubで彼をフォークし、ソースコードにいくつかの機能を追加しました。 http://goo.gl/oW4hX 注:私はまだコードを改良しており、セキュリティ侵害の可能性があるかどうかテストしています。 – Tohid

2

データが十分に小さく、セキュリティ上の懸念がない場合は、Cookieを使用できます。同じHttpContext.Currentベースのアプローチが有効です。

リクエストと応答HTTPヘッダーを使用して、サービスコール間で情報を渡すこともできます。 Global.asaxの中

+0

私はこれが古いと知っていますが、このことについて誰かに読んでもらうのに役立ちます。 CORS ajaxリクエストを実行するためにXDomainRequestを使用している場合、IE8/9でのCookieの使用には制限があります。あなたはそれについてもっと読むことができます[ここ](http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx) – elvin

79

それに打撃を与える

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

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

を追加します。WEBAPI 2で)

+0

これはうまくいきました!どうもありがとうございました!トップの答えはroute.RouteHandlerはWeb APIで同じタイプではないため動作していないので動作しませんでした。この答えはこの問題を解決しました。 – Tikkes

+10

+1あなたが何をしているのか分かっているなら、特別な場合にはWeb ApiでSessionを使用するのは大丈夫だと思います。 – nima

+6

これを使用して、一部のページが非常に遅くなりました。要求がWeb APIであるかどうかをテストする方が良いでしょう。if(HttpContext.Current.Request.Url.AbsolutePath.StartsWith( "/ api /")) – nima

20

あなたは次にGlobal.asaxの

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

にこれを追加することができます可能性セッション:

HttpContext.Current.Session 
+3

これは他の回答にどのように追加しますか? –

+0

@eddie_catを置くだけで、彼はPostAuthorizeに入れます。それでも、これをより良くするために、nimaが指摘しているようにリクエストがapiリクエストであれば、条件付きチェックを追加してポイントすることができます。 – Suamere

1

ここで説明したように、2017年にはASP.Net Coreを使用しています。

Microsoft.AspNetCore.Sessionパッケージは、セッション状態を管理するためのミドルウェアを提供します。

Introduction to session and application state in ASP.NET Core

すでにワーキングプロジェクトに

関連する問題