具有不同会话 mvc 的多个浏览器选项卡
Multiple browser tabs with different sessions mvc
该项目允许客户为各种类型的风险项目投保 (wheelchair/vehicle/scooter)。为每个风险项目创建了不同的路线(因为对每种类型提出了不同的问题)。目前可以选择一个风险项目,然后客户填写他们的所有信息,获得报价,然后接受保单(通过 credit/debit 卡支付)。创建此应用程序是为了每份保单仅投保一个风险项目。如果客户只想投保一个风险项目,所有这些都可以正常工作。如果客户端然后 select 以确保不同的风险(或另一个)项目,问题仍然存在,因为浏览器现在持有先前请求的会话。
我需要找到一种方法来允许报价和接受不同(或相同)的风险项目,而不会干扰以前的政策开始(支付)。
当客户选择一个风险项目(来自不同的网站)时,它将导航到风险项目的第一个起点,打开一个不同的选项卡。是否可以为每个选项卡维护一个会话?
这就是完成的...
注册路线(文件引用 Global.asax)
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Scooter",
url: "Scooter/{action}/{id}",
defaults: new { controller = "Mobility", action = "All", id = UrlParameter.Optional}
);
routes.MapRoute(
name: "Wheelchair",
url: "Wheelchair/{action}/{id}",
defaults: new { controller = "Mobility", action = "All", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "ComingSoon", id = UrlParameter.Optional }
);
}
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
BundleMobileConfig.RegisterBundles(BundleTable.Bundles);
//Add a required data annotation that relies on the value of another property to set the field as required
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(RequiredIfAttribute),typeof(RequiredAttributeAdapter));
}
正在创建会话:
#region Helpers
private static T GetSession<T>(string key)
{
object value = HttpContext.Current.Session[key];
if (value == null)
return default(T);
else
return ((T)value);
}
private static void SetSession(string key, object value)
{
HttpContext.Current.Session[key] = value;
}
public static void ClearQuoteSession()
{
HttpContext.Current.Session.Clear();
HttpContext.Current.Session.Abandon();
}
public static string GenerateBuyMapCode()
{
var holderKey = Guid.NewGuid();
var polMapCode = "BB-" + holderKey;
return polMapCode.Trim();
}
以下方法允许使用 cookie 创建会话。
public static PolicyBase CreateNewPolicyBase(Enums.RiskType type)
{
var polBase = new PolicyBase();
polBase.Insured = new InsuredViewModel();
polBase.RiskMeItems = new List<RiskItemMeModel>();
*Irrelevant code removed*
polBase.SessionKey = GenerateBuyMapCode();
polBase.BrowserSession = HttpContext.Current.Session;
*Irrelevant code removed*
return polBase;
}
#region Session INIT
public static string QuoteKey
{
get { return GetSession<string>("QuoteKey"); }
set { SetSession("QuoteKey", value); }
}
public static AusEnums.RiskType RiskType
{
get { return GetSession<AusEnums.RiskType>("RiskType"); }
set { SetSession("RiskType", value); }
}
public static AusEnums.QuoteArea Area
{
get { return GetSession<AusEnums.QuoteArea>("QuoteArea"); }
set { SetSession("QuoteArea", value); }
}
public static PolicyBase PolicyBase
{
get { return GetSession<PolicyBase>("PolicyBase"); }
set { SetSession("PolicyBase", value); }
}
public static SSMultiPremium MultiPremium
{
get { return GetSession<SSMultiPremium>("MultiPremium"); }
set { SetSession("MultiPremium", value); }
}
web.config
<sessionState mode="InProc" cookieless="UseDeviceProfile" regenerateExpiredSessionId="true" timeout="20" />
机动性和机动性风险项目起点不同,以下为机动性起点(以客户为准)
[HttpGet]
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]
public ActionResult Insured()
{
//We need to determine the direction
SessionHelper.GetRoutePath((Route)ControllerContext.RouteData.Route);
var polBase = SessionHelper.PolicyBase;
HttpCookie userCookie = new HttpCookie("BBCookieCheck");
userCookie["Name"] = "BB";
userCookie.Expires.AddDays(1); // cookie will expire after 1 days
Response.Cookies.Add(userCookie);
var viewModel = new InsuredViewModel();
if (polBase != null)
{
viewModel = polBase.Insured;
viewModel.Title = polBase.Insured.Title;
}
viewModel.riskType = SessionHelper.RiskType;
*Irrelevant code removed*
return View(viewModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Insured(InsuredViewModel model)
{
*Irrelevant code removed*
//create a new quote object and save the relevant fields
var polBase = SessionHelper.PolicyBase;
if (model.Id == 0)
{
polBase = SessionHelper.CreateNewPolicyBase(model.riskType);
*Irrelevant code removed*
}
}
看来您的用例可能会受益于 cookieless session 状态跟踪。
看起来你也差不多在那里。
<sessionState cookieless="UseUri" regenerateExpiredSessionId="true" timeout="20" />
UseDeviceProfile
几乎意味着任何现代浏览器都会使用 cookie。但是,如果您专门将其锁定为 UseUri
,您可能会获得更好的结果。
在这种情况下,您的 GetSession<string>("XXX")
可能变得多余,因为每个会话只与一个策略流程相关
该项目允许客户为各种类型的风险项目投保 (wheelchair/vehicle/scooter)。为每个风险项目创建了不同的路线(因为对每种类型提出了不同的问题)。目前可以选择一个风险项目,然后客户填写他们的所有信息,获得报价,然后接受保单(通过 credit/debit 卡支付)。创建此应用程序是为了每份保单仅投保一个风险项目。如果客户只想投保一个风险项目,所有这些都可以正常工作。如果客户端然后 select 以确保不同的风险(或另一个)项目,问题仍然存在,因为浏览器现在持有先前请求的会话。
我需要找到一种方法来允许报价和接受不同(或相同)的风险项目,而不会干扰以前的政策开始(支付)。 当客户选择一个风险项目(来自不同的网站)时,它将导航到风险项目的第一个起点,打开一个不同的选项卡。是否可以为每个选项卡维护一个会话?
这就是完成的...
注册路线(文件引用 Global.asax)
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Scooter",
url: "Scooter/{action}/{id}",
defaults: new { controller = "Mobility", action = "All", id = UrlParameter.Optional}
);
routes.MapRoute(
name: "Wheelchair",
url: "Wheelchair/{action}/{id}",
defaults: new { controller = "Mobility", action = "All", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "ComingSoon", id = UrlParameter.Optional }
);
}
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
BundleMobileConfig.RegisterBundles(BundleTable.Bundles);
//Add a required data annotation that relies on the value of another property to set the field as required
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(RequiredIfAttribute),typeof(RequiredAttributeAdapter));
}
正在创建会话:
#region Helpers
private static T GetSession<T>(string key)
{
object value = HttpContext.Current.Session[key];
if (value == null)
return default(T);
else
return ((T)value);
}
private static void SetSession(string key, object value)
{
HttpContext.Current.Session[key] = value;
}
public static void ClearQuoteSession()
{
HttpContext.Current.Session.Clear();
HttpContext.Current.Session.Abandon();
}
public static string GenerateBuyMapCode()
{
var holderKey = Guid.NewGuid();
var polMapCode = "BB-" + holderKey;
return polMapCode.Trim();
}
以下方法允许使用 cookie 创建会话。
public static PolicyBase CreateNewPolicyBase(Enums.RiskType type)
{
var polBase = new PolicyBase();
polBase.Insured = new InsuredViewModel();
polBase.RiskMeItems = new List<RiskItemMeModel>();
*Irrelevant code removed*
polBase.SessionKey = GenerateBuyMapCode();
polBase.BrowserSession = HttpContext.Current.Session;
*Irrelevant code removed*
return polBase;
}
#region Session INIT
public static string QuoteKey
{
get { return GetSession<string>("QuoteKey"); }
set { SetSession("QuoteKey", value); }
}
public static AusEnums.RiskType RiskType
{
get { return GetSession<AusEnums.RiskType>("RiskType"); }
set { SetSession("RiskType", value); }
}
public static AusEnums.QuoteArea Area
{
get { return GetSession<AusEnums.QuoteArea>("QuoteArea"); }
set { SetSession("QuoteArea", value); }
}
public static PolicyBase PolicyBase
{
get { return GetSession<PolicyBase>("PolicyBase"); }
set { SetSession("PolicyBase", value); }
}
public static SSMultiPremium MultiPremium
{
get { return GetSession<SSMultiPremium>("MultiPremium"); }
set { SetSession("MultiPremium", value); }
}
web.config
<sessionState mode="InProc" cookieless="UseDeviceProfile" regenerateExpiredSessionId="true" timeout="20" />
机动性和机动性风险项目起点不同,以下为机动性起点(以客户为准)
[HttpGet]
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]
public ActionResult Insured()
{
//We need to determine the direction
SessionHelper.GetRoutePath((Route)ControllerContext.RouteData.Route);
var polBase = SessionHelper.PolicyBase;
HttpCookie userCookie = new HttpCookie("BBCookieCheck");
userCookie["Name"] = "BB";
userCookie.Expires.AddDays(1); // cookie will expire after 1 days
Response.Cookies.Add(userCookie);
var viewModel = new InsuredViewModel();
if (polBase != null)
{
viewModel = polBase.Insured;
viewModel.Title = polBase.Insured.Title;
}
viewModel.riskType = SessionHelper.RiskType;
*Irrelevant code removed*
return View(viewModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Insured(InsuredViewModel model)
{
*Irrelevant code removed*
//create a new quote object and save the relevant fields
var polBase = SessionHelper.PolicyBase;
if (model.Id == 0)
{
polBase = SessionHelper.CreateNewPolicyBase(model.riskType);
*Irrelevant code removed*
}
}
看来您的用例可能会受益于 cookieless session 状态跟踪。 看起来你也差不多在那里。
<sessionState cookieless="UseUri" regenerateExpiredSessionId="true" timeout="20" />
UseDeviceProfile
几乎意味着任何现代浏览器都会使用 cookie。但是,如果您专门将其锁定为 UseUri
,您可能会获得更好的结果。
在这种情况下,您的 GetSession<string>("XXX")
可能变得多余,因为每个会话只与一个策略流程相关