【问题标题】:MVC6 Globally scoped valueMVC6 全局范围的值
【发布时间】:2015-11-15 19:43:51
【问题描述】:

我正在尝试为数据库提取网站名称,这是模型:

 public class Store
 {
     public int Id { get; set; }
     public string StoreName { get; set; }
 }

我想要做的只是对这些信息提出一个数据库请求。

这个SiteName目前在导航栏中使用,但可能会在其他地方使用。

我为导航栏创建了一个 ViewComponent:

public class NavbarViewComponent : ViewComponent
    {
        private IStoreRepository _storeRepository;
        private string _storeName;
        public NavbarViewComponent(IStoreRepository storeRepository)
        {
            _storeRepository = storeRepository;
            _storeName = _storeRepository.GetStoreById(1).StoreName;
        }
        public IViewComponentResult Invoke()
        {
            return View((object)_storeName);
        }
    }

这样访问:

@model string
<nav class="navbar navbar-default navbar-fixed-top">
    <div class="container-fluid">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" asp-controller="App" asp-action="Index">@Model</a> <!-- Here -->
...

问题是每次加载页面时都会调用数据库来获取它,这是可以理解的。但是,我不确定如何通过 one 调用存储库来访问 SiteName 并将其存储以备将来使用。

我考虑将它加载到会话变量中,但实际上它应该 100% 的时间是持久的。

【问题讨论】:

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


    【解决方案1】:

    编辑

    如果这是一个跨应用程序使用的变量,下面的信息是个好主意。但是,在这种情况下,问题是关于动态商店名称。结尾部分在这里不起作用。

    我处理多租户应用程序的一种方法是创建一个获取商店名称的包装函数。基本上,将名称存储在 HttpContext 缓存中并使用包装函数从缓存中获取值,或者如果未命中,则从数据库中获取。

    public string GetStoreNameById(int id){
       var httpContext = HttpContext.Current;
       //if no httpContext, just return from the db
       //rare but could throw a NullRefEx
       if(httpContext == null) return db.GetStore(id).Name;
       //build your key
       var key = string.format("Store-{0}", id);
       //if we get a cache miss, add the item from the db
       if(httpContext.Items[key] == null){
          var storeName = db.GetStore(id).Name;
          //note: there are overloads of this function for expiry times, etc.
          httpContext.Items.Add(key, storeName);
       }
       //return the value
       return httpContext.Items[key];
    }
    

    适用于非动态变量

    这听起来应该是 web.config 中的设置。快速获取值,并且可以从应用程序中运行的任何程序集访问。

    <appSettings>
        <add key="StoreName" value="My Store"/>
    </appSettings>
    

    并获取此值:

    var storeName = ConfigurationManager.AppSettings["StoreName"];
    

    【讨论】:

    • 这是一个很好的答案,将其存储在配置中可能是最好的方法,因此我将其标记为正确答案。我什至不需要数据库调用来获取信息。由于每个“商店”都部署在不同域上的自己的容器中。我可以在部署时操纵 config.json。谢谢汤米
    • @Jezzabeanz - 我刚刚注意到您使用的是 .NET 5,您能否针对第 5 版和第 5 版之间的任何差异进行编辑?这应该适用于 v 4.6 及更低版本,但不确定 5 的语法。
    • @Tommy:您确定 Items 容器是应用范围设置的最佳选择吗?
    • 说实话,我还不确定如何以编程方式操作 config.json(我只试用了 V5 和 MVC 6 几个小时)。
    • @WiktorZychla - 怎么会这样?我很乐意接受更好的想法!
    猜你喜欢
    • 1970-01-01
    • 2011-03-17
    • 2020-05-03
    • 2014-02-22
    • 2019-08-08
    • 2012-04-29
    • 2021-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多