51

画像を提供するためにASP.NetMVCでActionResultを作成しています。セッション状態を有効にすると、IISは同じユーザーからの要求を一度に1つだけ処理します。(これはMVCだけではありません。)

したがって、このアクションを呼び出す複数の画像があるページでは、一度に1つの画像リクエストのみを処理できます。同期です。

この画像アクションを非同期にしたい-前の画像リクエストを完了する必要なしに、実行ごとに複数の画像リクエストを実行したい。(イメージが単なる静的ファイルである場合、IISはそれらをこの方法で提供します。)

そのため、そのアクションの呼び出しに対してのみセッションを無効にするか、特定のリクエストにセッション状態がないことを指定したいと思います。これがMVCでどのように行われるか知っている人はいますか?ありがとう!

4

8 に答える 8

57

イメージコントローラーが実際にセッションへの読み取り専用アクセスを必要とする状況に誰かがいる場合は、コントローラーにSessionState属性を設定できます。

[SessionState(SessionStateBehavior.ReadOnly)]

詳細については、 http://msdn.microsoft.com/en-us/library/system.web.mvc.sessionstateattribute.aspxを参照してください。

https://stackoverflow.com/a/4235006/372926に感謝します

于 2012-01-09T23:16:58.043 に答える
37

このためのアクションフィルターを実装するのではなく、なぜ実装しませんRouteHandlerか?

これが取引です-1IRouteHandlerつの方法があります- GetHttpHandler。コントローラーに対してASP.NetMVC要求を行う場合、既定では、ルーティングエンジンは、の新しいインスタンスを作成することによって要求を処理します。これによりMvcRouteHandler、が返されますMvcHandlerMvcHandlerの実装はIHttpHandler(サプライズ!)IRequiresSessionStateインターフェースでマークされています。これが、通常のリクエストがセッションを使用する理由です。

画像を提供するためのカスタム(MvcRouteHandlerを使用する代わりに)を実装する方法についての私のブログ投稿に従う場合は、セッションタグ付きの戻りをスキップできます。 RouteHandlerIHttpHandler

これにより、IISが同期を強制する必要がなくなります。また、フィルターを処理するMVCコードのすべてのレイヤーをスキップするため、パフォーマンスが向上する可能性があります。

于 2009-09-23T06:29:05.343 に答える
9

私も同じ問題に遭遇し、研究開発を行った後、このリンクは私のために働きました参照: https ://techatfingers.wordpress.com/2016/06/14/session-state-on-action/

  1. カスタム属性を作成する
  2. DefaultControllerFactoryクラスに存在する「GetControllerSessionBehavior」メソッドをオーバーライドします。
  3. global.aspxに登録します

1>カスタム属性を作成

public sealed class ActionSessionStateAttribute : Attribute
    {
            public SessionStateBehavior SessionBehavior { get; private set; }          
            public ActionSessionStateAttribute(SessionStateBehavior sessionBehavior)
            {
                SessionBehavior = sessioBehavior;
            }
    }

2.オーバーライド

public class SessionControllerFactory : DefaultControllerFactory
{       
        protected override SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, Type controllerType)
        {
            if (controllerType == null)
                return SessionStateBehavior.Default;

            var actionName = requestContext.RouteData.Values["action"].ToString();
            Type typeOfRequest=requestContext.HttpContext.Request.RequestType.ToLower() =="get"?typeof(HttpGetAttribute):typeof(HttpPostAttribute);
            // [Line1]
            var cntMethods = controllerType.GetMethods()
                   .Where(m => 
                    m.Name == actionName &&
                    (  (  typeOfRequest == typeof(HttpPostAttribute) && 
                          m.CustomAttributes.Where(a => a.AttributeType == typeOfRequest).Count()>0
                       )
                       ||
                       (  typeOfRequest == typeof(HttpGetAttribute) &&
                          m.CustomAttributes.Where(a => a.AttributeType == typeof(HttpPostAttribute)).Count() == 0
                       )
                    )
                );
            MethodInfo actionMethodInfo = actionMethodInfo = cntMethods != null && cntMethods.Count() == 1 ? cntMethods.ElementAt(0):null;
            if (actionMethodInfo != null)
            {
                var sessionStateAttr = actionMethodInfo.GetCustomAttributes(typeof(ActionSessionStateAttribute), false)
                                    .OfType<ActionSessionStateAttribute>()
                                    .FirstOrDefault();

                if (sessionStateAttr != null)
                {
                    return sessionStateAttr.Behavior;
                }
            }
            return base.GetControllerSessionBehavior(requestContext, controllerType);
 }

3.Global.asaxにクラスを登録します

public class MvcApplication : System.Web.HttpApplication
 {
        protected void Application_Start()
        {
            // --- other code ---
            ControllerBuilder.Current.SetControllerFactory(typeof(SessionControllerFactory));
        }
}
于 2016-06-15T08:13:24.047 に答える
7

別のドメインからの画像を提供してみてください。つまり、images.mysite.comのようなものです。

これには2つの利点があります。1つは、セッションがCookieによって追跡されるため、images.mysite.comにはCookieがありません。2つ目は、画像を取得するための追加の2つの同時リクエストを提供することです。

画像を提供するためにHttpHandlerを設定することを検討しましたか?

于 2009-09-23T06:11:01.207 に答える
5

mvc3を使用する場合、SessionState属性は非常に役立ちます。mvc2でこれを実現する方法には、もう少しコーディングが必要です。

アイデアは、特定の要求がセッションオブジェクトを使用しないことをasp.netに伝えることです。

したがって、特定のリクエスト用のカスタムルートハンドラーを作成します

public class CustomRouteHandler : IRouteHandler
    {
        public System.Web.IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            requestContext.HttpContext.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.ReadOnly);
            return new MvcHandler(requestContext);
        }
    }

SessionStateBehavior列挙型には4つのメンバーがあります。非同期動作を取得するには、「無効」モードまたは「読み取り専用」モードを使用する必要があります。

このカスタムルートハンドラーを作成したら、特定のリクエストがこのハンドラーを通過することを確認してください。これは、Global.asaxで新しいルートを定義することで実行できます

routes.Add("Default", new Route(
                "{controller}/{action}",
               new RouteValueDictionary(new { controller = "Home", action = "Index"}),
               new CustomRouteHandler()
                ));

このルートを追加すると、すべてのリクエストがカスタムルートハンドラークラスによって処理されるようになります。さまざまなルートを定義することで、具体的にすることができます。

于 2012-02-11T16:38:47.290 に答える
3

DefaultCOntrollerFactoryをカスタムControllerFactoryクラスに変更します。デフォルトのController.TempDataProviderはSessionStateTempDataProviderを使用します。あなたはそれを変えることができます。

1.web.config/system.web/sessionState:mode="Off"を設定します。

2.DictionaryTempDataProviderクラスを作成します。

  public class DictionaryTempDataProvider : ITempDataProvider
  {
    public IDictionary<string, object> LoadTempData(ControllerContext controllerContext)
    {
      return new Dictionary<string, object>();
    }

    public void SaveTempData(ControllerContext controllerContext, IDictionary<string, object> values)
    {
    }
  }

3.DictionaryTempDataControllerFactoryを作成します

  public class DictionaryTempDataControllerFactory : DefaultControllerFactory
  {
    public override IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
    {
      var controller = base.CreateController(requestContext, controllerName) as Controller;
      if (controller!=null)
        controller.TempDataProvider = new DictionaryTempDataProvider();

      return controller;
    }
  }

4. global.asax.cs Apprication_Startイベントで、DictionaryTempDataControllerFactoryを設定します。

protected void Application_Start()
{
  RegisterRoutes(RouteTable.Routes);

  ControllerBuilder.Current.SetControllerFactory(
   new DictionaryTempDataControllerFactory()
  );
}
于 2009-09-23T15:29:12.043 に答える
1

私たちのサーバーでは、IISはセッションについてさえ知りません-一度にセッションごとに1つの要求を処理するのはASP.NETスタックです。画像などの静的ファイルは影響を受けません。

ASP.NETアプリがIISではなくファイルを提供している可能性はありますか?

于 2009-09-23T06:36:19.830 に答える
1

新しいコントローラーを作成する

[SessionState(SessionStateBehavior.Disabled)]でコントローラーを飾ります

そのコントローラーに対して無効化された状態で表示するコードをリファクタリングする

于 2013-09-27T12:58:27.940 に答える