Проблемы с регистрацией MVC5 DisplayModeProvider
Поэтому у меня есть приложение MVC 5 с 3 режимами отображения: рабочий стол (по умолчанию), мобильный телефон и планшет. Я использую WURFL, чтобы выяснить устройства. Вот код, вызываемый из global.cs для регистрации:
public static void RegisterDisplayModes(IList<IDisplayMode> displayModes){
var datafile = HttpContext.Current.Server.MapPath(WurflDataFilePath);
var configurer = new InMemoryConfigurer().MainFile(datafile);
var manager = WURFLManagerBuilder.Build(configurer);
HttpContext.Current.Cache[WURFLMANAGER_CACHE_KEY] = manager;
bool mobileEnabled = ConfigurationManager.AppSettings["EnableMobileSite"] == "true";
bool tabletEnabled = ConfigurationManager.AppSettings["EnableTabletSite"] == "true";
var modeDesktop = new DefaultDisplayMode("") {
ContextCondition = (c => c.Request.IsDesktop())
};
var modeMobile = new DefaultDisplayMode("mobile"){
ContextCondition = (c => c.Request.IsMobile())
};
var modeTablet = new DefaultDisplayMode("tablet"){
ContextCondition = (c => c.Request.IsTablet())
};
displayModes.Clear();
if (mobileEnabled) displayModes.Add(modeMobile);
if (tabletEnabled) displayModes.Add(modeTablet);
displayModes.Add(modeDesktop);
}
Я использую некоторые методы расширения для HttpRequestBase, как описано в http://msdn.microsoft.com/en-us/magazine/dn296507.aspx:
public static bool IsDesktop(this HttpRequestBase request){
return true;
}
public static bool IsMobile(this HttpRequestBase request) {
return IsMobileInternal(request.UserAgent) && !IsForcedDesktop(request);
}
public static bool IsTablet(this HttpRequestBase request) {
return IsTabletInternal(request.UserAgent) && !IsForcedDesktop(request);
}
public static void OverrideBrowser(this HttpRequestBase request, bool forceDesktop){
request.RequestContext.HttpContext.Cache[OVERRIDE_BROWSER_CACHE_KEY] = forceDesktop;
}
public static bool IsForcedDesktop(this HttpRequestBase request){
var isForced = request.RequestContext.HttpContext.Cache[OVERRIDE_BROWSER_CACHE_KEY];
return isForced != null ? isForced.ToString().ToBool() : false;
}
private static bool IsMobileInternal(string userAgent) {
var device = WURFLManagerBuilder.Instance.GetDeviceForRequest(userAgent);
if (device.IsTablet() == true) {
return false;
} else {
return device.IsMobile();
}
}
private static bool IsTabletInternal(string userAgent) {
var device = WURFLManagerBuilder.Instance.GetDeviceForRequest(userAgent);
return device.IsTablet();
}
Некоторое время все работает нормально, но через час или около того мобильные и планшетные устройства начинают отображать представления рабочего стола, а представление рабочего стола начинает отображать общее представление ViewSwitcher (я предполагаю, что большинство людей знакомы с ним, оно просто позволяет вам чтобы показать рабочий стол с мобильного устройства). Это почти как та ошибка кеширования в mvc4. Я попытался удалить свой код, чтобы зарегистрировать режимы отображения, и просто пошел с мобильной поддержкой mvc по умолчанию, и он работает нормально, у него та же проблема! Ясно, что где-то здесь есть проблема... кто-нибудь может увидеть что-нибудь очевидное? Почти невозможно отладить, потому что проблемы начинают появляться только через долгое время, и даже тогда только в реальной системе! Есть идеи?
Спасибо, куча... был по этому вопросу слишком долго сейчас... Ура Энди
РЕДАКТИРОВАТЬ: даже удаление его обратно к реализации по умолчанию создает проблему. Я добавил некоторый отладочный код, чтобы убедиться, что я на самом деле запускаю mvc5, но, похоже, так и есть. Я также попробовал изначально рекомендованный способ решения проблемы на mvc4, отключив кэш, но все равно не радуюсь. Неужели нет никого с информацией об этом?
1 ответ
Вот и я наконец понял это. Очень просто, как обычно. По какой-то причине я использовал RequestContext.HttpContext.Cache для сохранения статуса, когда кто-то хочет получить полный просмотр, а не мобильный просмотр. Я никогда не использовал HttpContext.Cache, я почти уверен, что взял бы это где-нибудь из блога - но больше не могу его найти. Так что все, что произошло, было то, что это изменило бы мнение для всех, а не только для одного человека. Не могу поверить, что потребовались недели, чтобы понять это. Надеюсь, это поможет кому-то еще в какой-то момент.