2009-07-27 8 views
1

私は、リクエストごとにCommunityPrincipal(IPrincipalインターフェイスを実装する)オブジェクトを作成するHttpModuleを持っています。私は何とかすべてのリクエストのためにオブジェクトを保管したいと思います。私はキャストをやっていなくても必要なときにいつでもそれを得ることができます。リクエスト中に同じオブジェクトにアクセス/使用する - asp.net

基本的には、私はFormsAuthenticationModuleの仕組みを模倣したいと思っています。 HttpContext.Userプロパティは、すべての要求に対してIPrincipalインターフェイスを実装するオブジェクトを割り当てます。

私は何とかHttpContext.MySpecialUser(またはMySpecialContext.MySpecialUser - 静的クラスを作成できます)を呼び出して、自分のオブジェクト(特定の型)を返すことができるようにしたいと考えています。

私は拡張メソッドを使うことができましたが、要求中にアクセスできるようにオブジェクトを格納する方法はわかりません。

これはどのように達成できますか?

特定の型(CommunityPrincipal - オブジェクトとしてではなく)として保存したいことに注意してください。 もちろん、現在のリクエストは処理され、他のすべてのスレッド/リクエストとは共有されません。

私は自分のCommunityPrincipalオブジェクトをHttpModuleのHttpContext.Userに割り当てますが、IPrincipalインターフェイスで定義されていないCommunityPrincipalオブジェクトでプロパティを使用する必要があるたびにキャストを行う必要があります。

答えて

0

カスタムプリンシパルをContext.Userに割り当てるのは正しいです。うまくいけば、あなたはApplication_AuthenticateRequestでそれをやっているでしょう。

質問には、ASPXページからのユーザーオブジェクトにしかアクセスできませんか?そうなら、キャストを含むカスタムベースページを実装することができます。

public class CommunityBasePage : Page 
{ 
    new CommunityPrincipal User 
    { 
     get { return base.User as CommunityPrincipal; } 
    } 
} 

は、その後、あなたのページがCommunityBasePageから継承させると、あなたはthis.Userからすべてのプロパティを取得することができるでしょう。

+0

ご返信ありがとうございます。 これも良い考えです。私は通常、コントローラまたはビューのsooで私はカスタムビューと私が継承することができるカスタムコントローラを作成することができますそれを使用します。ありがとう。 – MartinF

0

あなたはすでにあなたが本当にあなたの目標をacheiveする必要があるすべてはあなたの目標をacheives staticメソッドであるHttpContext.Userプロパティにオブジェクトを格納するので: -

public static class MySpecialContext 
    { 
    public static CommunityPrinciple Community 
    { 
     get 
     { 
      return (CommunityPrinciple)HttpContext.Current.User; 
     } 
    } 
    } 

今、あなたのようにCommunityPrincipleを得ることができます: -

var x = MySpecialContext.Community; 

それは避けるようになったために多くの労力を思わしかし: -

var x = (CommunityPrinciple)Context.User; 

代替はのHttpContextの拡張メソッドのようになります。 -

public static class HttpContextExtensions 
    { 
    public static CommunityPrinciple GetCommunity(this HttpContext o) 
    { 
     return (CommunityPrinciple)o.User; 
    } 
    } 

使用それ: -

var x = Context.GetCommunity(); 

かなりきちんとしたのですが、拡張クラスが定義されている名前空間を含めることを忘れないためにあなたを必要とすること各ファイルのusingリストに必要です。

編集

(ところで、私はどのような状況を理解することは、本当に興味があると思いますが、上記のように呼ばれるコード内で行わでもキャストはまだ受け入れられない理由はいくつかの本当に良い理由を持っている瞬間を仮定しましょうこの結論につながります)。

さらに別の代替はThreadStaticフィールドである: -

public class MyModule : IHttpModule 
    { 
    [ThreadStatic] 
    private static CommunityPrinciple _threadCommunity; 

    public static CommunityPrinciple Community 
    { 
     get 
     { 
      return _threadCommunity; 
     } 
    } 
    // Place here your original module code but instead of (or as well as) assigning 
    // the Context.User store in _threadCommunity. 
    // Also at the appropriate point in the request lifecyle null the _threadCommunity 

    } 

[ThreadStatic]飾らフィールドはスレッドごとの記憶の1つのインスタンスを有することになります。したがって、複数のスレッドは_threadCommunityを変更して読み取ることができますが、それぞれはそのフィールドの特定のインスタンスで動作します。

+0

ご返信ありがとうございます。それは私がすでにやっていることです:)。私が求めているのは、CommunityPrincipalオブジェクトを使用する必要があるたびに、明示的なキャストを避ける方法があるかどうかです。それをCommunityPrincipalとして保存し、すべてのリクエストで利用できるようにするいくつかのテクニックがある場合。 Etc私はスレッド(ThreadStaticAttribute)ごとに "作成"された静的クラスを作成することを考えていましたが、オブジェクトがすべての要求の最後に削除されるようにセキュリティの問題があるかどうかはわかりません。スレッドは共有/再利用されます。 – MartinF

1

データをスレッド自体に結合することを避けることをお勧めします。 asp.netがスレッドを現在または将来どのように使用するかを制御することはできません。

データは要求コンテキストに非常に結びついているため、コンテキストと共に定義され、生きていて、死ぬべきです。それはそれを配置するための適切な場所であり、オブジェクトをHttpModuleにインスタンス化することも適切です。

キャストは本当に大した問題ではないはずですが、そのことから離れたいのであれば、これに対してHttpContextの拡張メソッドをお勧めします。これはちょうど拡張メソッド処理するように設計されています。ここで

は、私はそれを実装したい方法です:

は、拡張メソッドを置くために静的クラスを作成します。あなたのHttpModuleをで

public static class ContextExtensions 
{ 
    public static CommunityPrinciple GetCommunityPrinciple(this HttpContext context) 
    { 
     if(HttpContext.Current.Items["CommunityPrinciple"] != null) 
     { 
      return HttpContext.Current.Items["CommunityPrinciple"] as CommunityPrinciple; 
     } 
    } 
} 

を同じように、コンテキスト・アイテムのコレクションに校長を置く:

HttpContext.Current.Items.Add("CommunityPrincipal", MyCommunityPrincipal); 

通常のコンテキストのユーザープロパティを自然状態に保ち、サードパーティのコード、フレームワークコード、その他何か書いたものが、通常のIPrincipalがそこでストロークしていた。このインスタンスは、有効であるユーザーの要求中にのみ存在します。そして、何よりも、このメソッドはまるで通常のHttpContextメンバであるかのようにコード化することができ、キャストは必要ありません。

+0

あなたの返事をありがとう。 私は、オブジェクトをcontext.userにIPrincipalとして格納し、拡張メソッドを使用して任意の型に明示的にキャストします。それは私が得ることができる最高のようです。 拡張メソッドを持たず、HttpContext.Items経由でHttpContext上にオブジェクトとして格納する代わりに、context.userのように使うことができる特定の型のプロパティを何らかの形で作ることができることを期待しました。どうやらない。 – MartinF

関連する問題