0

因此,我正在构建一个 Web 应用程序,一旦完成,我就想出售它。它允许用户在管理面板中输入数据,例如他们的网站名称、元关键字、他们的联系电子邮件、电话、地址等。我编写了一个操作过滤器,以便在我放置过滤器的每个请求中包含这些值,因此我不必每次都查询它们,因为这些值包含在整个站点的公共页脚中。但是,我了解到,如果我用这些值的新信息或不同信息更新数据库,它不会在网页上更新,我猜这是因为操作过滤器是在应用程序启动时配置的。在操作过滤器中,我使用存储库模式来查询这些值。我在下面包含了操作过滤器的代码。我怎样才能拥有操作过滤器的便利,但能够在数据库中的数据发生变化时动态更新它?谢谢!

public class ViewBagActionFilter : ActionFilterAttribute,IActionFilter
{
    Repositories.SettingsRepository _repo = new Repositories.SettingsRepository();

    void IActionFilter.OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);
    }

    void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
    {
        string siteName = _repo.GetSiteName();
        string siteDesc = _repo.GetSiteDescription();
        string siteKeywords = _repo.GetSiteKeywords();
        string googleAnalytics = _repo.GetGoogleAnalytics();
        string streetAddress = _repo.GetStreetAddress();
        string zipCode = _repo.GetZipCode();
        string city = _repo.GetCity();
        string state = _repo.GetState();
        string aboutUs = _repo.GetAboutUs();
        string phone = _repo.GetPhoneNumber();
        string contactEmail = _repo.GetContactEmail();

        if (!string.IsNullOrWhiteSpace(siteName) && siteName.Length > 0)
        {
            string[] splitSiteName = new string[siteName.Length/2];
            splitSiteName = siteName.Split(' ');
            if (splitSiteName.Length > 1)
            {
                filterContext.Controller.ViewBag.SiteName1 = splitSiteName[0];
                filterContext.Controller.ViewBag.SiteName2 = splitSiteName[1];
            }
            else
            {
                filterContext.Controller.ViewBag.SiteName1 = splitSiteName[0];
                filterContext.Controller.ViewBag.SiteName2 = "";
            }
        }
        //Set default values for common viewbag items that are on every page using ternary syntax
        filterContext.Controller.ViewBag.SiteDescription = (!string.IsNullOrWhiteSpace(siteDesc) && siteDesc.Length > 0) ? siteDesc : "";
        filterContext.Controller.ViewBag.SiteKeywords = (!string.IsNullOrWhiteSpace(siteKeywords) && siteKeywords.Length > 0) ? siteKeywords : "";
        filterContext.Controller.ViewBag.GoogleAnalytics = (!string.IsNullOrWhiteSpace(googleAnalytics) && googleAnalytics.Length > 0) ? googleAnalytics : "";
        filterContext.Controller.ViewBag.StreetAddress = (!string.IsNullOrWhiteSpace(streetAddress) && streetAddress.Length > 0) ? streetAddress : "";
        filterContext.Controller.ViewBag.ZipCode = (!string.IsNullOrWhiteSpace(zipCode) && zipCode.Length > 0) ? zipCode : "";
        filterContext.Controller.ViewBag.City = (!string.IsNullOrWhiteSpace(city) && city.Length > 0) ? city : "";
        filterContext.Controller.ViewBag.State = (!string.IsNullOrWhiteSpace(state) && state.Length > 0) ? state : "";
        filterContext.Controller.ViewBag.AboutUs = (!string.IsNullOrWhiteSpace(aboutUs) && aboutUs.Length > 0) ? aboutUs : "";
        filterContext.Controller.ViewBag.PhoneNumber = (!string.IsNullOrWhiteSpace(phone) && phone.Length > 0) ? phone : "";
        filterContext.Controller.ViewBag.ContactEmail = (!string.IsNullOrWhiteSpace(contactEmail) && contactEmail.Length > 0) ? contactEmail : "";
        base.OnActionExecuting(filterContext);   
    }
}
4

1 回答 1

1

我将尝试解释动作过滤器的工作原理。

因此,如果您扩展 Action 过滤器,您可以覆盖 4 个基本方法:

  • OnActionExecuting – 在执行控制器操作之前调用此方法。
  • OnActionExecuted – 在执行控制器操作后调用此方法。
  • OnResultExecuting – 在执行控制器操作结果之前调用此方法。
  • OnResultExecuted – 在执行控制器操作结果后调用此方法。

所以这意味着你的方法每次都会在 Controller 运行操作之前被调用。

现在关于优化。你有

string siteName = _repo.GetSiteName();
        string siteDesc = _repo.GetSiteDescription();
        string siteKeywords = _repo.GetSiteKeywords();
        string googleAnalytics = _repo.GetGoogleAnalytics();
        string streetAddress = _repo.GetStreetAddress();
        string zipCode = _repo.GetZipCode();
        string city = _repo.GetCity();
        string state = _repo.GetState();
        string aboutUs = _repo.GetAboutUs();
        string phone = _repo.GetPhoneNumber();
        string contactEmail = _repo.GetContactEmail();

我建议你创建一个类

public class Site{
 public string SiteName{get;set;}
public string City{get;set;}
//And so on just to add all properties
}

然后在存储库中添加另一种方法

_repo.GetSite(); //Which will return object Site

然后

filterContext.Controller.ViewBag.CurrentSite = _repo.GetSite(); 

现在对你来说可能是最重要的。为什么它不能按您的意愿工作,而且有点简单。属性类仅在应用程序启动时初始化一次,之后它不会重新加载,并且您的实现有点奇怪,因为

 Repositories.SettingsRepository _repo = new Repositories.SettingsRepository();

我想你在这里加载设置。因此,在您加载后,您不再重新加载它......这意味着每次重新加载页面时您都会得到相同的结果,但是如果您重新启动 iis,您将刷新数据。 可能的解决方案

将 _repo 的初始化移动到 OnActionExecuting 然后它将每次重新加载数据,或者按照我的建议重写存储库和

filterContext.Controller.ViewBag.CurrentSite = _repo.GetSite(); 

应始终从 db 加载新数据。

希望能帮助到你 :)

于 2014-01-13T20:35:25.197 回答