如何在Orchard CMS中填充部分会话数据

时间:2012-03-18 13:02:11

标签: asp.net asp.net-mvc asp.net-mvc-3 orchardcms

我正在尝试从驱动程序中的HTTP会话返回ContentPart。以下是我的Driver和ContentPart的代码:

public class UnpersistedPartDriver : ContentPartDriver<UnpersistedPart>
{
    public Localizer T { get; set; }
    private readonly IHttpContextAccessor _httpContextAccessor;

    public UnpersistedPartDriver(IHttpContextAccessor httpContextAccessor) {
        T = NullLocalizer.Instance;
        _httpContextAccessor = httpContextAccessor;
    }

    /// <summary>
    /// This method is responsible for displaying your part in the frontend.
    /// </summary>
    /// <param name="part">Your part.</param>
    /// <param name="displayType"></param>
    /// <param name="shapeHelper"></param>
    /// <returns></returns>
    protected override DriverResult Display(UnpersistedPart part, string displayType, dynamic shapeHelper)
    {
        var session = _httpContextAccessor.Current().Session;
        var cart = session["Cart"] as UnpersistedPart;
        if (cart == null) {
            cart = new UnpersistedPart();
            session["Cart"] = cart;
        }

        return ContentShape("Parts_Jumpstart_Unpersisted",
            () => shapeHelper.Parts_Jumpstart_Unpersisted(ContentPart: part));
    }

    // There is nothing to edit and update, so we don't need Editor methods.
}
public class UnpersistedPart : ContentPart
{
    public UnpersistedPart()
    {
        this.Items = new List<Item>();
        this.Items.Add(new Item { Id = 1, Title = "Book 1", Price = "130.00", Quantity = "1" });
        this.Items.Add(new Item { Id = 2, Title = "Book 2", Price = "145.00", Quantity = "2" });
        this.Items.Add(new Item { Id = 3, Title = "Book 3", Price = "150.00", Quantity = "3" });
    }

    public IList<Item> Items;
    public string Total
    {
        get 
        {
            return Items.Sum(i => i.Total).ToString();
        }
    }
    public string SessionId;
}

[Serializable]
public class Item
{
    public int Id;
    public string Title;
    public string Price;
    public string Quantity;
    public decimal Total { get { return decimal.Parse(Price) * int.Parse(Quantity); } }
}

当我将零件更改为购物车时:

return ContentShape("Parts_Jumpstart_Unpersisted",
            () => shapeHelper.Parts_Jumpstart_Unpersisted(ContentPart: part));

为:

return ContentShape("Parts_Jumpstart_Unpersisted",
            () => shapeHelper.Parts_Jumpstart_Unpersisted(ContentPart: cart));

它不会显示任何内容。我得到一个空文章标签:

&lt; article class =“content-item book”shape-id =“0”&gt;&lt; / article&gt;

1 个答案:

答案 0 :(得分:5)

空标记通常表示后台存在异常。 请查看/ App_Data / Logs。

我看到你想要实现的目标,但你应该以不同的方式做到这一点。

最佳做法是利用内容处理程序的OnLoading事件,使用来自不同来源的数据填充零件属性,例如。会话。 将整个部分存储在会话中肯定会在某些时候遇到麻烦,特别是当部件绑定到数据库记录时。

处理程序应执行所有准备操作。

驱动程序应仅在即用型零件上保存与显示/编辑器相关的逻辑(例如选择正确的形状,准备视图模型)。所以司机大部分时间都应该保持简单。

所以在你的情况下,步骤将是:

  1. 创建一个派生自ContentHandler
  2. 的CartHandler
  3. 在1. 中创建的处理程序中使用OnLoading事件,以使用会话中的数据来保存属性/ ies
  4. 示例:

    public class CartHandler : ContentHandler
    {
        public CartHandler(IHttpContextAccessor context)
        {
            this.OnLoaded<UnpersistedPart>(ctx, part =>
            {
                var session = context.GetCurrent().Session;
                // Here comes loading data from session
    
                part.MyProperty = session["Something"]; 
                // ........ 
            });
        }
    }
    

    每次显示包含它的内容项时,都会调用此事件,然后再显示它。因此,在驱动程序中,您将收到一个完全填充的部分。

    添加处理程序后,您的驱动程序Display方法看起来会简单得多:

    protected override DriverResult Display(UnpersistedPart part, string displayType, dynamic shapeHelper)
    {
        return ContentShape("Parts_Jumpstart_Unpersisted",
            () => shapeHelper.Parts_Jumpstart_Unpersisted(ContentPart: part));
    }