我在 母版页 中有以下代码来加载一些自定义内容,例如css文件,页脚中的一些地址信息,页眉/页脚logo等。我面临的加载时间长达一分钟!这是 可怕的 练习,我知道 - 我只是将其破解以使其正常运行。加载此类自定义信息的最佳做法是什么?
目前,我尝试加载一个cookie - 检查它是否具有所需的密钥,如果它没有 - 从数据库加载信息。我希望有一些类似于.config文件,如果可能的话,它会缓存在客户端机器上。
所有信息都存储在名为StoreSettings的表中,该表通过StoreSettingsID链接到Reseller表。
<head id="Head1">
<%
HttpCookie storeSettingsCookie = Request.Cookies["StoreSettings"];
try
{
if (storeSettingsCookie == null || storeSettingsCookie.HasKeys == false)
{
if (Context.User.Identity.IsAuthenticated && Context.User.IsInRole("Reseller"))
{
var reseller = new Reseller();
var storeSettings = new StoreSettings();
var resellerRepository = new ResellerRepository();
reseller = resellerRepository.GetResellerByUsername(Context.User.Identity.Name);
if (reseller.StoreSettingsID != null && reseller.StoreSetting.Theme != null)
{
var storeSettingsRepository = new StoreSettingsRepository();
storeSettings = storeSettingsRepository.GetStoreSettings((int)reseller.StoreSettingsID);
storeSettingsCookie = new HttpCookie("StoreSettings");
storeSettingsCookie["HeaderImage"] = storeSettings.Image1.FileName;
storeSettingsCookie["FooterImage"] = storeSettings.Image.FileName;
storeSettingsCookie["ThemeLocation"] = storeSettings.Theme.StylesheetLocation;
storeSettingsCookie["StoreName"] = storeSettings.StoreName;
storeSettingsCookie["Address1"] = storeSettings.Address1;
storeSettingsCookie["Address2"] = storeSettings.Address2;
storeSettingsCookie["City"] = storeSettings.City;
storeSettingsCookie["PostalCode"] = storeSettings.PostalCode;
storeSettingsCookie["ProvinceCode"] = storeSettings.Province.Abbreviation;
storeSettingsCookie["Phone"] = storeSettings.Phone;
Response.Cookies.Add(storeSettingsCookie);
}
else
{
storeSettingsCookie = new HttpCookie("StoreSettings");
storeSettingsCookie["ThemeLocation"] = "~/Content/jquery-ui-1.8.9.custom.css";
storeSettingsCookie["StoreName"] = "";
storeSettingsCookie["Address1"] = "";
Response.Cookies.Add(storeSettingsCookie);
}
}
}
}
catch
{
}
%>
<title>
<asp:ContentPlaceHolder ID="TitleContent" runat="server" />
|
<%: string.IsNullOrEmpty(storeSettingsCookie["StoreName"]) ? "My Store Name" : storeSettingsCookie["StoreName"] %>
</title>
... <%-- Css/JS --%>
</head>
任何建议都表示赞赏。我期待来自MVC人员的很多叹息。我知道这不是MVC的工作方式,所以请不要提醒我,哈哈。 :)
修改的
好的,所以按照LukLed的建议,我已经创建了一个基本控制器类,将上面的代码粘贴在它的构造函数中并让我的控制器继承它。这似乎可以工作,但User对象为null。我应该如何解决这个问题?这就是我所拥有的:
public BaseController()
{
var resellerRepository = new ResellerRepository();
var reseller = resellerRepository.GetResellerByUsername(User.Identity.Name);
if (reseller.StoreSettingsID != null && reseller.StoreSetting.Theme != null)
{
var storeSettingsRepository = new StoreSettingsRepository();
var storeSettings = storeSettingsRepository.GetStoreSettings((int)reseller.StoreSettingsID);
ViewData["HeaderImage"] = storeSettings.Image1.FileName;
ViewData["FooterImage"] = storeSettings.Image.FileName;
ViewData["ThemeLocation"] = storeSettings.Theme.StylesheetLocation;
ViewData["StoreName"] = storeSettings.StoreName;
ViewData["Address1"] = storeSettings.Address1;
ViewData["Address2"] = storeSettings.Address2;
ViewData["City"] = storeSettings.City;
ViewData["PostalCode"] = storeSettings.PostalCode;
ViewData["ProvinceCode"] = storeSettings.Province.Abbreviation;
ViewData["Phone"] = storeSettings.Phone;
}
else
{
ViewData["ThemeLocation"] = "~/Content/jquery-ui-1.8.9.custom.css";
ViewData["StoreName"] = "";
ViewData["Address1"] = "";
}
}
经销商必须登录才能查看商店。
修改的
所以这是我在遵循Darins建议后所处的位置 - 我升级到MVC3并使用了一个GlobalActionFilter,它在调用每个动作后执行。我如何防止这种情况 - 因为它执行4-5次。此外 - 每次viewdata都为null。我做错了什么?
这是我的动作过滤器(我没有使用Darin的示例中的Automapper,因为StoreSettings没有直接转换为StoreSettingsViewModel,我希望看到这个工作,首先)
public class StoreSettingsActionFilter : ActionFilterAttribute
{
private readonly IResellerRepository _resellerRepository;
private readonly IStoreSettingsRepository _storeSettingsRepository;
public StoreSettingsActionFilter(
IResellerRepository resellerRepository,
IStoreSettingsRepository storeSettingsRepository
)
{
_resellerRepository = resellerRepository;
_storeSettingsRepository = storeSettingsRepository;
}
public StoreSettingsActionFilter()
: this(new ResellerRepository(), new StoreSettingsRepository())
{
}
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
base.OnResultExecuted(filterContext);
var settingsViewModel = new StoreSettingsViewModel();
settingsViewModel.ThemeLocation = "~/Content/jquery-ui-1.8.9.custom.css";
var user = filterContext.HttpContext.User;
if (!user.Identity.IsAuthenticated || !user.IsInRole("Reseller"))
{
filterContext.Controller.ViewData["storeSettings"] = settingsViewModel;
return;
}
var session = filterContext.HttpContext.Session;
var reseller = session["reseller"] as Reseller;
if (reseller == null)
{
reseller = _resellerRepository.GetResellerByUsername(user.Identity.Name);
session["reseller"] = reseller;
}
if (reseller.StoreSettingsID != null && reseller.StoreSetting.Theme != null)
{
var storeSettings = session["storeSettings"] as StoreSettings;
if (storeSettings == null)
{
storeSettings = _storeSettingsRepository.GetStoreSettings((int)reseller.StoreSettingsID);
session["storeSettings"] = storeSettings;
}
// Using AutoMapper to convert between the model and the view model
//settingsViewModel = Mapper.Map<StoreSettings, StoreSettingsViewModel>(storeSettings);
settingsViewModel.ThemeLocation = storeSettings.Theme.StylesheetLocation;
settingsViewModel.Address1 = storeSettings.Address1;
settingsViewModel.Address2 = storeSettings.Address2;
settingsViewModel.City = storeSettings.City;
settingsViewModel.FooterImage = storeSettings.Image.FileName;
settingsViewModel.HeaderImage = storeSettings.Image1.FileName;
settingsViewModel.Phone = storeSettings.Phone;
settingsViewModel.PostalCode = storeSettings.PostalCode;
settingsViewModel.ProvinceCode = storeSettings.Province.Abbreviation;
settingsViewModel.StoreName = storeSettings.StoreName;
}
filterContext.Controller.ViewData["storeSettings"] = settingsViewModel;
}
}
这是我注册全局动作过滤器的地方
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
//Register the global action filter
GlobalFilters.Filters.Add(new StoreSettingsActionFilter());
//RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
答案 0 :(得分:2)
我会使用一个动作过滤器,它会在每个请求上注入商店设置。视图模型可能如下所示:
public class StoreSettingsViewModel
{
public string HeaderImage { get; set; }
public string FooterImage { get; set; }
public string ThemeLocation { get; set; }
public string StoreName { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string PostalCode { get; set; }
public string ProvinceCode { get; set; }
public string Phone { get; set; }
}
动作过滤器:
public class StoreSettingsActionFilter : ActionFilterAttribute
{
private readonly IResellerRepository _resellerRepository;
private readonly IStoreSettingsRepository _storeSettingsRepository;
public StoreSettingsActionFilter(
IResellerRepository resellerRepository,
IStoreSettingsRepository storeSettingsRepository
)
{
_resellerRepository = resellerRepository;
_storeSettingsRepository = storeSettingsRepository;
}
public StoreSettingsActionFilter()
: this(new ResellerRepository(), new StoreSettingsRepository())
{ }
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
base.OnResultExecuted(filterContext);
var settingsViewModel = new StoreSettingsViewModel();
settingsViewModel.ThemeLocation = "~/Content/jquery-ui-1.8.9.custom.css";
var user = filterContext.HttpContext.User;
if (!user.Identity.IsAuthenticated || !user.IsInRole("Reseller"))
{
filterContext.Controller.ViewData["storeSettings"] = settingsViewModel;
return;
}
var session = filterContext.HttpContext;
var reseller = session["reseller"] as Reseller;
if (reseller == null)
{
reseller = _resellerRepository.GetResellerByUsername(user.Identity.Name);
session["reseller"] = reseller;
}
if (reseller.StoreSettingsID != null && reseller.StoreSetting.Theme != null)
{
var storeSettings = session["storeSettings"] as StoreSettings;
if (storeSettings == null)
{
storeSettings = _storeSettingsRepository.GetStoreSettings((int)reseller.StoreSettingsID);
session["storeSettings"] = storeSettings;
}
// Using AutoMapper to convert between the model and the view model
settingsViewModel = Mapper.Map<StoreSettings, StoreSettingsViewModel>(storeSettings);
}
filterContext.Controller.ViewData["storeSettings"] = settingsViewModel;
}
}
现在我们需要在基本控制器上应用此属性,以便为每个操作执行它:
[StoreSettings]
public abstract class BaseController : Controller
{
}
如果您使用的是ASP.NET MVC 3,则可以使用global action filter。
最后,在母版页中,您可以访问商店设置:
<%
var storeSettings = (StoreSettingsViewModel)ViewData["storeSettings"];
%>
<title>
<asp:ContentPlaceHolder ID="TitleContent" runat="server" />
<%: storeSettings.StoreName ?? "My Store Name" %>
</title>
<%-- Css/JS --%>
...