You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET6站点无法将BasketItem添加到Cart Session的问题

.NET6 Umbraco站点Session购物车无法持久化问题排查

问题描述

构建.NET6 Umbraco站点时,从HttpContext.Current.Session切换到新Session方案后,触发AddToBasket动作能创建Session和BasketItem实例,但无法将BasketItem加入Cart Session,视图中获取的Cart始终为null,导致/basket页面无法显示商品项。


关键问题与修复方案

1. Session中间件注册顺序错误

Session中间件必须在Umbraco中间件之前注册,否则Umbraco的请求处理逻辑会先执行,Session无法绑定到当前请求上下文。

修复后Configure方法:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    // 先注册Session相关中间件
    app.UseCookiePolicy();
    app.UseSession();

    app.UseUmbraco()
        .WithMiddleware(u =>
        {
            u.UseBackOffice();
            u.UseWebsite();                    
        })
        .WithEndpoints(u =>
        {
            u.UseInstallerEndpoints();
            u.UseBackOfficeEndpoints();
            u.UseWebsiteEndpoints();
        });
}

2. Cart修改后未重新持久化到Session

GetCart()从Session获取Cart实例后,调用AddProduct修改了内部集合,但修改后的Cart没有重新保存回Session,导致Session中的Cart始终是初始空状态。

修复后ProductPageAddToBasket方法:

[HttpPost]
public IActionResult ProductPageAddToBasket(decimal productPrice)
{
    if (!ModelState.IsValid)
        return CurrentUmbracoPage();

    bool addedToCart = false;

    if (productPrice > 0)
    {
        var cart = GetCart();
        addedToCart = cart.AddProduct(CurrentPage, 1, productPrice);
        // 修改后必须重新保存到Session
        SessionHelper.SetObjectsession(HttpContext.Session, "Cart", cart);

        TempData[addedToCart ? "success" : "failure"] = 
            addedToCart ? "商品已成功加入购物车..." : "加入购物车时出错,请重试...";
    }
    return RedirectToCurrentUmbracoPage();
}

3. SessionHelper泛型方法硬编码类型问题

原SessionHelper.GetObjectsession硬编码返回Cart类型,无法支持泛型复用,且视图中类型引用可能存在匹配问题。

修复后SessionHelper类:

public static class SessionHelper
{
    public static void SetObjectsession(this ISession session, string key, object value)
    {
        session.SetString(key, JsonConvert.SerializeObject(value));
    }

    public static T GetObjectsession<T>(this ISession session, string key) where T : class, new()
    {
        var value = session.GetString(key);
        return string.IsNullOrEmpty(value) ? new T() : JsonConvert.DeserializeObject<T>(value);
    }
}

4. Cart私有字段无法被序列化

Cart类中的private List<BasketItem> lineCollection是私有字段,Json.NET默认不会序列化私有字段,导致Session中保存的Cart没有商品数据。

修复方案二选一:

  • 方案1:将私有字段改为公共属性
public class Cart
{
    public List<BasketItem> LineCollection { get; set; } = new List<BasketItem>();

    // AddProduct方法修改为使用LineCollection
    public bool AddProduct(IPublishedContent productPage, int quantity, decimal price)
    {
        BasketItem line = LineCollection.FirstOrDefault(product => product.ProductPage.Id == productPage.Id);
        // 剩余逻辑不变
    }
}
  • 方案2:给私有字段添加序列化特性
public class Cart
{
    [JsonProperty]
    private List<BasketItem> lineCollection = new List<BasketItem>();

    // 原AddProduct逻辑不变
}

5. BasketItem中复杂类型序列化问题

IPublishedContent是Umbraco的复杂类型,直接序列化会导致数据异常,建议改用商品ID存储,而非直接存储实例:

public class BasketItem
{
    public int ProductPageId { get; set; }
    public int Quantity { get; set; }
    public decimal Price { get; set; }
    public bool IsOptionalExtra { get; set; }
    public bool IsMainProduct { get; set; }
    public string Description { get; set; }
    public int? ExtraMainProductPageId { get; set; }
}

6. 视图类型引用一致性问题

确保视图中Cart类型的命名空间与后端一致,建议在视图顶部添加命名空间引用:

@using YourProjectNamespace.Models
@{
    var basketCart = HttpContext.Session.GetObjectsession<Cart>("Cart");
}

内容的提问来源于stack exchange,提问作者StuartP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 07:54:53