我应该如何从.NetCore2中的模型访问HttpContext?

时间:2018-10-07 09:16:45

标签: c# asp.net-core .net-core

我想在我的UI中使用Dev Express AspxLtreeList控件并将其绑定到.NetCore2 API中的数据

对于ASP和.NetCore来说,我都是新手。

我可以吗,如果可以的话,如何将以下代码转换为.NetCore?

using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace TreeListDragDropMultipleNodes.Models
{
    public class Data
    {
        public int ID { set; get; }
        public int ParentID { set; get; }
        public string Title { set; get; }
    }

    public static class DataHelper
    {
        public static List<Data> GetData()
        {
            List<Data> data = HttpContext.Current.Session["Data"] as List<Data>;

            if (data == null)
            {
                data = new List<Data>();

                data.Add(new Data { ID = 1, ParentID = 0, Title = "Root" });

                data.Add(new Data { ID = 2, ParentID = 1, Title = "A" });
                data.Add(new Data { ID = 3, ParentID = 1, Title = "B" });
                data.Add(new Data { ID = 4, ParentID = 1, Title = "C" });

                data.Add(new Data { ID = 5, ParentID = 2, Title = "A1" });
                data.Add(new Data { ID = 6, ParentID = 2, Title = "A2" });
                data.Add(new Data { ID = 7, ParentID = 2, Title = "A3" });

                data.Add(new Data { ID = 8, ParentID = 3, Title = "B1" });
                data.Add(new Data { ID = 9, ParentID = 3, Title = "B2" });

                data.Add(new Data { ID = 10, ParentID = 4, Title = "C1" });

                data.Add(new Data { ID = 11, ParentID = 8, Title = "B1A" });
                data.Add(new Data { ID = 12, ParentID = 8, Title = "B1B" });

                HttpContext.Current.Session["Data"] = data;
            }

            return data;
        }

        public static void MoveNodes(int[] nodeKeys, int parentID)
        {
            var data = GetData();
            var processedNodes = data.Join(nodeKeys, x => x.ID, y => y, (x, y) => x);

            foreach(var node in processedNodes)
            {
                if (processedNodes.Where(x => x.ID == node.ParentID).Count() == 0)
                {
                    if (node.ParentID == 0)
                    {
                        MakeParentNodeRoot(parentID);
                    }
                    node.ParentID = parentID;
                }
            }
        }

        public static void MoveNode(int nodeID, int parentID)
        {
            var data = GetData();

            var node = data.Find(x => x.ID == nodeID);

            if (node.ParentID == 0)
            {
                MakeParentNodeRoot(parentID);
            }

            node.ParentID = parentID;
        }

        public static void MakeParentNodeRoot(int id)
        {
            GetData().Find(x => x.ID == id).ParentID = 0;
        }
    }
}

1 个答案:

答案 0 :(得分:3)

由于{.net-core中没有IHttpContextAccessor,因此您需要找到一种方法将HttpContext.Current注入到依赖类中。

要转换当前代码,请先将辅助程序重构为非静态的,并且还应使用抽象/接口作为后盾

public interface IDataHelper {
    List<Data> GetData();
    void MoveNodes(int[] nodeKeys, int parentID);
    void MoveNode(int nodeID, int parentID);
    void MakeParentNodeRoot(int id);
}

通过IHttpContextAccessor的构造函数注入使类遵循显式依赖关系

public class DataHelper : IDataHelper {
    private readonly IHttpContextAccessor accessor;

    public DataHelper(IHttpContextAccessor accessor) {
        this.accessor = accessor;
    }

    public List<Data> GetData() {
        List<Data> data = accessor.HttpContext.Session.Get<List<Data>>("Data");

        if (data == null) {
            data = new List<Data>();
            data.Add(new Data { ID = 1, ParentID = 0, Title = "Root" });
            data.Add(new Data { ID = 2, ParentID = 1, Title = "A" });
            data.Add(new Data { ID = 3, ParentID = 1, Title = "B" });
            data.Add(new Data { ID = 4, ParentID = 1, Title = "C" });
            data.Add(new Data { ID = 5, ParentID = 2, Title = "A1" });
            data.Add(new Data { ID = 6, ParentID = 2, Title = "A2" });
            data.Add(new Data { ID = 7, ParentID = 2, Title = "A3" });
            data.Add(new Data { ID = 8, ParentID = 3, Title = "B1" });
            data.Add(new Data { ID = 9, ParentID = 3, Title = "B2" });
            data.Add(new Data { ID = 10, ParentID = 4, Title = "C1" });
            data.Add(new Data { ID = 11, ParentID = 8, Title = "B1A" });
            data.Add(new Data { ID = 12, ParentID = 8, Title = "B1B" });

            accessor.HttpContext.Session.Set("Data", data);
        }

        return data;
    }

    public void MoveNodes(int[] nodeKeys, int parentID) {
        var data = GetData();
        var processedNodes = data.Join(nodeKeys, x => x.ID, y => y, (x, y) => x);

        foreach(var node in processedNodes) {
            if (processedNodes.Where(x => x.ID == node.ParentID).Count() == 0) {
                if (node.ParentID == 0) {
                    MakeParentNodeRoot(parentID);
                }
                node.ParentID = parentID;
            }
        }
    }

    public void MoveNode(int nodeID, int parentID) {
        var data = GetData();
        var node = data.Find(x => x.ID == nodeID);
        if (node.ParentID == 0) {
            MakeParentNodeRoot(parentID);
        }
        node.ParentID = parentID;
    }

    public void MakeParentNodeRoot(int id) {
        GetData().Find(x => x.ID == id).ParentID = 0;
    }
}

需要一些额外的扩展名才能在会话中存储数据

//Extensions used to stores complex objects as JSON string in session
public static class SessionExtensions {
    public static void Set(this ISession session, string key, object value) {
        session.SetString(key, JsonConvert.SerializeObject(value));
    }

    public static T Get<T>(this ISession session, string key) {
        var value = session.GetString(key);
        return value == null ? default(T) : JsonConvert.DeserializeObject<T>(value);
    }
}

配置服务集合以允许在请求时解决所需的依赖项。

services.AddScoped<IDataHelper, DataHelper>();
services.AddHttpContextAccessor();//IHttpContextAccessor is not added by default.

任何依赖于数据助手的类现在也都需要重构,以依赖于其抽象。

这将使代码更简洁,更易于管理,因为它将与静态实现问题分离开来。