【问题标题】:How should I access HttpContext from a model in .NetCore2?我应该如何从 .NetCore2 中的模型访问 HttpContext?
【发布时间】:2018-10-07 09:16:45
【问题描述】:

我想在我的 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;
        }
    }
}

【问题讨论】:

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


【解决方案1】:

您需要找到将IHttpContextAccessor 注入依赖类的方法,因为HttpContext.Current 在.net-core 中不可用。

要转换当前代码,首先将帮助器重构为不是静态的,它还应该由抽象/接口支持

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.

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

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

【讨论】:

  • 我看过所有使用接口将 HttpContext 注入类、配置 Startup.cs,然后在控制器的构造函数中“注入”的示例。但是现在我的新类现在有一个用于注入的构造函数,例如:' public class Order { public Order(IHttpContextAccessor accessor) { ... } }' 我从 Controller 构造函数调用它 MyController(IOrder order) 将初始化并注入,但是。 .. 如果需要直接初始化我的类(我们做了很多),比如说'var oder = new Order(); ' 我需要通过访问器吗?这是第一个问题。
猜你喜欢
  • 1970-01-01
  • 2019-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多