画像を提供するためにASP.Net MVCでActionResultを作成しています。セッション状態を有効にすると、IISは、同じユーザーからの一度に1つの要求のみを処理します(これはMVCだけではありません)。
したがって、このアクションにコールバックする複数の画像があるページでは、一度に1つの画像リクエストしか処理できません。同期です。
この画像のアクションを非同期にしたい-前のものを完了する必要なく、各実行に対する複数の画像リクエストが欲しい。 (画像が静的ファイルのみの場合、IISはこの方法で画像を提供します。)
そのため、そのアクションの呼び出しに対してのみセッションを無効にするか、特定のリクエストにセッション状態がないことを指定します。誰もがこれがMVCでどのように行われるか知っていますか?ありがとう!
これにアクションフィルターを実装するのではなく、RouteHandler
を実装してみませんか?
これが取引です-IRouteHandler
には1つのメソッド-GetHttpHandler
があります。コントローラーにASP.Net MVC要求を行うと、デフォルトでは、ルーティングエンジンはMvcRouteHandler
の新しいインスタンスを作成して要求を処理し、MvcHandler
を返します。 MvcHandler
はIHttpHandler
の実装であり、(驚き!)IRequiresSessionState
インターフェースでマークされています。これが通常のリクエストがセッションを使用する理由です。
画像を提供するためにカスタムRouteHandler
を実装する方法について あなたは私のブログ投稿に従います の場合(MvcRouteHandlerを使用する代わりに)-セッションのタグが付けられたIHttpHandler
を返すのをスキップできます。
これにより、IIS=同期を強制する必要がなくなります。フィルターを処理するMVCコードのすべてのレイヤーがスキップされるため、パフォーマンスが向上する可能性があります。
イメージコントローラーが実際にセッションへの読み取り専用アクセスを必要とする状況に誰かがいる場合は、コントローラーにSessionState属性を設定できます
[SessionState(SessionStateBehavior.ReadOnly)]
詳細は http://msdn.Microsoft.com/en-us/library/system.web.mvc.sessionstateattribute.aspx を参照してください。
私も同じ問題に遭遇し、R&Dを行った後、このリンクは私のために機能しました参照: https://techatfingers.wordpress.com/2016/06/14/session-state-on-action/
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));
}
}
別のドメインから画像を提供してみてください。つまり、images.mysite.comのようなものです。
これには2つの利点があります。1つ目は、セッションがCookieによって追跡されるため、images.mysite.comにCookieがないことです。 2つ目は、画像を取得するための追加の2つの同時リクエストを提供します。
画像を提供するためにHttpHandlerを設定することを検討しましたか?
SessionState属性は、mvc3を使用する場合に非常に役立ちます。 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()
));
このルートを追加すると、すべてのリクエストがカスタムルートハンドラークラスによって処理されます。異なるルートを定義することで、特定のものにすることができます。
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()
);
}
新しいコントローラーを作成する
[SessionState(SessionStateBehavior.Disabled)]でコントローラーを装飾する
そのコントローラーに対して参照を無効にしたいリファクタリングコード
私たちのサーバーでは、IISはセッションについてさえ知りません。セッションごとに一度に1つの要求を処理するのはASP.NETスタックです。画像などの静的ファイルは影響を受けません。
ASP.NETアプリがIISではなくファイルを提供している可能性はありますか?