【问题标题】:Multiple browser tabs with different sessions mvc具有不同会话 mvc 的多个浏览器选项卡
【发布时间】:2020-04-19 17:31:19
【问题描述】:

该项目允许客户为各种类型的风险物品(轮椅/车辆/踏板车)投保。为每个风险项目创建了不同的路径(因为针对每种类型提出了不同的问题)。目前可以选择一个风险项目,然后客户填写所有信息,获取报价,然后接受保单(通过信用卡/借记卡支付)。创建此应用程序是为了只为每个保单的一个风险项目投保。如果客户只想为一个风险项目投保,所有这些都可以正常工作。如果客户端随后选择为不同的风险(或其他)项目投保,则问题仍然存在,因为浏览器现在持有上一个请求的会话。

我需要找到一种方法来允许不同(或相同)的风险项目被引用和接受,而不会干扰之前的保单开始(付款)。 当客户选择一个风险项目(来自不同的网站)时,它将导航到风险项目的第一个起点,打开一个不同的选项卡。是否可以为每个选项卡维护一个会话?

这就是我们所做的......

注册路线(参考 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*
        }
     }

【问题讨论】:

    标签: session asp.net-mvc-5 session-cookies mvcrazor


    【解决方案1】:

    看来您的用例可能会受益于cookieless session 状态跟踪。 看来你也差不多了。

        <sessionState cookieless="UseUri" regenerateExpiredSessionId="true" timeout="20" />
    

    UseDeviceProfile 几乎意味着任何现代浏览器都会求助于使用 cookie。但是,如果您专门将其锁定为 UseUri,您可能会得到更好的结果。

    在这种情况下,您的 GetSession&lt;string&gt;("XXX") 可能会变得多余,因为每个会话仅与一个策略流相关

    【讨论】:

      猜你喜欢
      • 2011-02-19
      • 1970-01-01
      • 2014-05-19
      • 1970-01-01
      • 2013-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多