【问题标题】:Insight into inheriting from a base controller class深入了解从基本控制器类继承
【发布时间】:2019-01-15 17:29:37
【问题描述】:

我正在使用 .NETCore 2.1、Entity Framework 和 Razor 页面来创建游戏管理系统。

我在 Microsoft.AspNetCore.Mvc 命名空间中有一个控制器,它连接到第 3 部分 API 并从中检索数据。

控制器有许多不同的方法,它们返回不同的东西,但它们都共享以下代码:

    public static GameSystemManager.LoginInfo gamerManagerLogin = new GameSystemManager.LoginInfo()
    {
        UserKey = "myAPIkey",
        Password = "xyzxyz"
    };

    public static GameSystemManager.GamerLister gamerLists = new GameSystemManager.GamerLister
    {
        MaxNumberResults = 15,
        PageNumber = 0
    };

所以一种控制器方法可能如下所示:

    public IActionResult GetAllGames(Guid Id)
    {

        public static GameSystemManager.LoginInfo gamerManagerLogin = new GameSystemManager.LoginInfo()
        {
            UserKey = "myAPIkey",
            Password = "xyzxyz"
        };

        public static GameSystemManager.GamerLister gamerLists = new GameSystemManager.GamerLister
        {
            MaxNumberResults = 15,
            PageNumber = 0
        };

        response = GameSystemManager.ListGames(gamerManagerLogin, gamerLists, Id);

        return View(response.Results);
    }

由于多个控制器和方法使用相同的代码,我决定创建一个基本控制器,并将该代码放在那里,并让其他控制器继承它。

这是我的 BaseController:

   public class BaseController : Controller
   {

        public static GameSystemManager.LoginInfo gamerManagerLogin = new GameSystemManager.LoginInfo()
        {
            UserKey = "myAPIkey",
            Password = "xyzxyz"
        };

        public static GameSystemManager.GamerLister gamerLists = new GameSystemManager.GamerLister
        {
            MaxNumberResults = 15,
            PageNumber = 0
        };

    }

我是这样使用它的:

public class GameListController : BaseController
{

    public IActionResult GetAllGames(Guid Id)
    {

        response = GameSystemManager.ListGames(gamerManagerLogin, gamerLists, Id);

        return View(response.Results);
    }

}

这是我的 appsettings.json:

  "GamerManager": {
    "UserKey": "myAPIkey",
    "Password": "xyzxyz"
  },

这是我的 GamerManagerConfig 类:

public class GamerManagerConfig
{
    readonly string UserKey = "myAPIkey";
    readonly string Password = "xyzxyz";
}

但是,它不起作用。我只是从 API 收到超时错误。它只有在我直接在控制器方法中有代码时才起作用,就像我上面的例子一样。

我认为这可能与初始化有关。也许它需要直接在方法中初始化?我不确定。

任何见解将不胜感激!

谢谢!

【问题讨论】:

  • 可能发布不起作用的代码比发布的代码更有帮助!
  • 谢谢!我添加了基本控制器
  • @Loofer 我也添加了使用基本控制器的方式。
  • 您的登录信息应该在外部配置中(用户机密、环境变量、Azure Key Vault 等),然后您应该将其注入您的控制器。带有您的页码和最大结果的静态也不应该是静态的。最大结果也应该在您的配置中,而页码根本不应该在那里,而应该来自请求。
  • @ChrisPratt 谢谢,但我只是从我的 Razor 页面点击控制器。我将如何传递该信息?再次感谢。

标签: razor asp.net-core entity-framework-6 asp.net-core-mvc


【解决方案1】:

您的登录信息应该在外部配置中(用户机密、环境变量、Azure Key Vault 等),然后您应该将其注入到您的控制器中。最大结果和页码也应该在外部配置中或作为参数提供给您的操作(如果您希望能够通过请求对其进行自定义)。

创建一个类:

public class GamerManagerConfig
{
    UserKey = "myAPIkey",
    Password = "xyzxyz"
}

在 Startup.cs 中将您的配置绑定到它:

services.Configure<GamerManagerConfig>(Configuration.GetSection("GamerManager"));

然后,在您的控制器中:

public class GameListController : Controller
{
    private readonly GamerManagerConfig _gamerManagerConfig;

    public GameListController(IOptions<GamerManagerConfig> gamerManagerConfig)
    {
        _gamerManagerConfig = gamerManagerConfig.Value;
    }

    public IActionResult GetAllGames(Guid id, page = 1, maxResults = 15)
    {
        var gamerManagerLogin = new GameSystemManager.LoginInfo
        {
            UserKey = _gamerManagerConfig.UserKey,
            Password = _gamerManagerConfig.Password
        };

        var gamerLists = new GameSystemManager.GamerLister
        {
            MaxNumberResults = maxResults,
            PageNumber = page
        };

        var response = GameSystemManager.ListGames(gamerManagerLogin, gamerLists, id);

        return View(response.Results);
    }
}

【讨论】:

  • 哇,太美了!我会看看我是否可以继续实施!
  • 所以我添加了公共类 GamerManagerConfig,然后将该行添加到我的 Startup.cs。但是,当将“私有只读 GamerManagerConfig”行添加到控制器时,它说它找不到对 GamerManagerConfig 的任何引用。我觉得我错过了一步。谢谢
  • 哦,等等,“GamerManager”应该是我的 appsettings.json 文件中的一个部分吗?
  • 是的。您可能需要添加 using 语句,具体取决于您放置该类的位置。
  • 但是,实际上不要使用 appsettings.json。在开发中使用用户机密。在生产中,您需要使用环境变量或 Azure Key Vault 之类的东西。将秘密放入 appsettings.json 会使它们提交给您的源代码管理,这很糟糕。
【解决方案2】:

试试下面的代码。我怀疑你的静态方法链接到 BaseController。

静态方法基本上是一种从面向对象回退的方法 概念。因此,它们在继承方面不是很灵活 层次结构,不可能直接做这样的事情。

response = GameSystemManager.ListGames(BaseController.gamerManagerLogin, BaseController.gamerLists, Id);

或者,您可以在 BaseController 中创建一个构造函数。当您从 GameListController 调用 Base 构造函数时,它可以使用正确的值初始化 GameSystemManager 对象。然后,您可以从基类访问属性。 Link to example

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-14
    • 1970-01-01
    • 2013-12-19
    • 2019-12-20
    • 2014-11-27
    • 1970-01-01
    • 2015-02-02
    相关资源
    最近更新 更多