2009-04-06 5 views
1

URLリダイレクトを使用して複数の(類似の)Webサイトを提供するWebサーバールートで1つのASP.NET Webアプリケーションを実行しています。実世界の例を与える:ASP.NET:単一のアプリケーション内の複数のセッションオブジェクト

http://webshopserver/company1/ProductList.aspx -> http://webshopserver/ProductList.aspx?showProductsFrom=company1 
http://webshopserver/company2/ProductList.aspx -> http://webshopserver/ProductList.aspx?showProductsFrom=company2 
... 

これは非常にうまく動作します。唯一の問題は、InProcセッションマネージャがセッションオブジェクトをAppDomainに格納しているため、これらの異なる店舗のすべてが同じセッションオブジェクトを共有することは明らかです。私はcompany1とcompany2の店舗に異なるセッションオブジェクトを持たせたいと思います。たとえば、ユーザーが同じブラウザウィンドウの異なるタブでcompany1とcompany2の店舗を開くと、company1のショッピングカートに入れられた商品が会社2のカートに現れません。

私は好きではない。この問題を解決するために、いくつかの明白なアプローチがあります。

  • は、それを格納し、その後何>と、HashMapの<会社名にすべてをカプセル化し、私自身のSessionオブジェクトを作成します。 "real" session:セッションオブジェクトを使用する既存のコードがすべて破損します。
  • セッションIDのCookieがドメインに結びついているため、http://company1.webshopserver/のようなURLとワイルドカードDNSレコードを使用します。実際には「webshopserver」に相当するため、これは醜いです。
  • 私自身のカスタムセッションプロバイダを作成:それは車輪を再発明するようなものでしょう。
  • 企業ごとに別々のIISアプリケーションを作成する:新しい企業を作成するには、http://webshopserver/CreateYourOwnWebshop.aspxのようなものを使用する必要があります。後で人的(サーバー管理者)の介入は必要ありません。

私はの線に沿って液のより考えています:URLに応じて、異なるのAppDomainを使用するようにASP.NETを伝えるhttp://webshopserver/<companyName>/

  • にセッションクッキーのパスを制限

    • を。

    したがって、これらの点の1つ(または別の解決法)を達成する方法に関する情報は役に立ちます。

  • +0

    申し訳ありませんが、私は別のIISアプリケーションでno-行くを逃しません。これは自己ホスト型のアプリですか、またはコントロールパネルにアクセスできる共有環境で動作していますか? – Kev

    +0

    問題ありません、とにかくあなたの答えに感謝します。それは(現在)自己ホスト型のアプリです。 – Heinzi

    答えて

    6

    会社に基づいているセッションオブジェクトの参照を、会社に基づいた動的キーで更新するのは最も簡単な解決策ではありませんか?

    Session["IsTest"] 
    

    createSessionKeyこれは、2つまたは分化になる会社の単純な連結とキー

    によっておそらく対応するキーを生成

    Session[createSessionKey(CompanyID, "IsTest")] 
    

    なる例えば

    ...生成されたキーを介してセッションにアクセスすることにより、より多くの企業が

    上記の例の後、company1は "company1_IsTest"キーを使用して "IsTest"セッション変数にアクセスし、company2は "company2_IsTest"キーを使用して同じ "IsTest"セッション変数にアクセスします。

    Session( "IsTest")がコードベース全体に散らばっていないと、コードのリファクタリングが本当の苦労になることは間違いありません。

    通常、セッション変数を厳密に型指定されたクラスに抽象化します。その後、私のセッション管理は1か所に含まれています。

    基本的なPageクラスを持ち、Sessionプロパティをオーバーライドするというアイデアを使うことは、すべてのSession変数を会社固有のものにするのが良い方法です。特定のセッションキーが汎用的なセッション変数か会社固有のものかどうかを判断できるのであれば、まだ有効です。

    +0

    質問(セッションラッパーの作成)で除外されたアプローチの1つですが、私はこれを答えとしてマークします。 – Heinzi

    1

    セッションにアイテムを追加したりセッションからアイテムを取得したりする方法(また、共通のベースページからページを派生させるかどうかによって決まる場合もあります)によっては、カスタムオブジェクトをラップすることができます。 (サイトでキーマップされたハッシュマップとしてセッションラッパーが実装されている最初のオプションで説明したように)すべてのコードを壊すことなく、カスタムオブジェクトを作成し、それをベースページレベルで「セッション」として公開すると、それはPageクラスから継承したSessionオブジェクトよりも優先されます。次に、カスタムオブジェクトはインデクサーをオーバーライドして、現在のhttpコンテキストのリクエストURLに基​​づいてこのオブジェクトを格納するハッシュマップのどこにあるかを判断します。

    共通の基本ページから派生していない場合は、参照を取得するために各ページの基本ページを実装するか、各ページにコードを追加する必要がありますあなたのオブジェクトに。ちょうどアイデア...

    1

    独自のセッションラッパーまたはカスタムセッションプロバイダを作成すると、の右にの回答が返されます。しかし、ユーザーがHttpModuleをPostAcquireRequestStateにフックして別の会社に行くと、既存のセッションデータを移動することでハッキングできます。

    基本的に、この製品は以前の製品と比較しています。これらが異なる場合は、既存のセッション値をすべてDictionary<string, object>に移動(または会社IDを前に付ける)し、この製品の保存済みDictionary<string, object>をセッションに復元します。以下のような

    何か:私はあなた自身のセッションのラッパーを書くことをお勧め

    void PostAcquireRequestState(object sender, EventArgs e) { 
        if (Session["ProductsFromCompany"] != Request["ProductsFromCompany"]) { 
         var lastCompanySession = new Dictionary<string, object>(Session.Count); 
         var sessionKeys = Session.Keys; 
         foreach (string key in sessionKeys) { 
         if (key == "CompanyState" || key == "ProductsFromCompany") { 
          continue; 
         } 
         lastCompanySession[key] = Session[key]; 
         Session.Remove(key); 
         } 
         Session["CompanyState"].Add(Session["ProductsFromCompany"], lastCompanySession); 
    
         var thisCompanySession = Session["CompanyState"][Request["ProductsFromCompany"]]; 
         foreach (string key in thisCompanySession.Keys) { 
         Session[key] = thisCompanySession[key]; 
         } 
         Session["CompanyState"].Remove(Request["ProductsFromCompany"]); 
    
         Session["ProductsFromCompany"] = Request["ProductsFromCompany"]; 
        } 
    } 
    
    関連する問題