Здравствуйте друзья, коллеги.
Вступление
Недавно решил создать свой блог. Поскольку я долгое время являюсь .NET разработчиком, мой выбор пал на один из немногих бесплатных .NET движков для создания блогов: Blog Engine .NET. Многие критикуют такой подход: мол блог не для того, что бы его "допиливать", а для того что бы писать посты.
Я придержуюсь другой точки зрения. Очень часто используя софт мне не хватает той или иной функции и очень круто по моему скромному мнению, когда есть возможность добавить (исправить) необходимую функцию. Вместо того, что бы ждать и надеяться: "А вдруг в очередном апдейте это исправят ?".
Так вот, скачав архив с уже собранным движком, я запустил его под IIS Express:
iisexpress.exe /path:"D:\Dev\www.rostislav.nikitin.blogengine.net"
Всё настроил, добавил пару постов и решил всё это дело где-то захостить.
Мой выбор пал на 60ти дневный SmarterASP.NET триал. Мой выбор был не случаен. Мне уже доводилось пользоваться этим хостингом и я на тот момент остался вполне доволен.
Итак, зарегестрировавшись (пришлось снова зарегистрироваться, что бы получить триал ещё раз) и загрузив приложение с на сервер, я был неприятно удивлён.
Проблема
При открытии главной страницы не было видно ни одного
поста, хотя их там должно было быть два - я добавлял их ещё в локальной версии
блога и в последствии успешно загрузив всю папку с локальным
блогом на сервер.
Однако я заметил что в разделе "AuthorList" было видно что таки в системе есть два
поста:
Это говорило о том, что они есть где то в системе, но почему то не отображаются на главной странице.
Повозившись немного я бросил это дело т.к. уже было поздно и хотелось спать. Было предчувствие, что это проблема кеширования.
Что интересно так это то, что на следующий день, зайдя на сайт, оба поста были на первой странице. Но внутренняя интуиция подсказывала - баг всё ещё здесь :) Поэтому, добавив пару тестовых постов я убедился, что интуиция меня не подвела - только что добавленных постов на странице не было.
Появилась мысль что проблема не в кешировании, а в чём то связанном со временем. CDN не был задействован, и в настройках блога я отключил кеширование и всю компрессию. Плюс ко всему Ctrl-F5 и очистка контента из кеша не помогли.
Суть проблемы
На самом деле проблема отказалась вот в чём. В типе BlogEngine.Core.Post есть два свойства: IsVisible и IsVisibleToPublic основываясь на значения которых принимается решение рендерить или не рендерить пост. Давайте посмотрим на код этих свойств:
/// <summary>
/// Gets a value indicating whether or not the post is visible or not.
/// </summary>
public bool IsVisible
{
get
{
if (this.IsDeleted)
return false;
else if (this.IsPublished && this.DateCreated <= DateTime.Now.AddHours(BlogSettings.Instance.Timezone))
return true;
else if (Security.IsAuthorizedTo(Rights.ViewUnpublishedPosts))
return true;
return false;
}
}
/// <summary>
/// Gets a value indicating whether a post is available to visitors not logged into the blog.
/// </summary>
public bool IsVisibleToPublic
{
get
{
return (this.IsPublished && this.DateCreated <= DateTime.Now.AddHours(BlogSettings.Instance.Timezone)) &&
this.IsDeleted == false;
}
}
Думаю Вы увидели в чём проблема. Если нет то в этом:
... this.DateCreated <= DateTime.Now.AddHours(BlogSettings.Instance.Timezone) ...
Исходя из вышеуказанного кода понятно, что для того что бы пост отображался на странице, дата его создания должна быть меньше текущей локальной даты на сервере + смещение соответствующей TimeZone. Это при том, что дата поста задаётся в браузере на клиенте и всегда является локальной датой пользователя (не сервера).
Я здесь вижу две ошибки, поправьте меня, если я ошибаюсь.
- Почему к DateTime.Now добавляется количество часов соответствующее тайм зоне, заданной в настройках ? Ведь DateTime.Now - это локальная дата сервера. Если уже преобразовывать дату к тайм зоне, которая задана в настройках бога, то делать это правильно - добавлять это значение к DateTime.UtcNow, вместо DateTime.Now. Тогда эта дата будет действительно отражать правильное время заданное при помощи настроек блога. Но это не основная проблема "выпадания" постов с главной страницы блога, хотя имеет своё влияние и в некоторых случаях (когда server.timeZone - BlogSettings.Instance.Timezone < 0) ведёт к уменьшению верхней границы, допустимых значений даты создания постов и ведёт к их "выпаданию" с главной страницы)
- Основная проблема состоит в том, что дата из браузера передаётся на сервер как локальная, но без тайм зоны в которой находится браузер. И сохраняется как локальная дата сервера. То есть 12:30 в браузере с тайм зоной +2 (12:30 TZ+2) сохраняется на сервере как 12:30 но с тайм зоной сервера +8 (12:30 TZ+8). Соответственно, когда доходит дело до проверки, то имеем следующее 12:30 TZ+2 <= 12:30 TZ+8 + BlogSettings.Instance.Timezone (+2) hours -> 12:30 TZ+2 <= 14:30 TZ+8 -> 10:30 <= 06:30 - что не верно и как результат пост не будет отображён
Решение
Немного подумав, я пришёл к выводу, что в данном случае проверка времени
поста абсолютно не нужна, как это рекомендует автор статьи "
Blog Post not visible in BlogEngine".
Для принятия решения, показывать или не показывать
пост вполне достаточно того, что он был опубликован и не был удалён. Поэтому я решил убрать проверку даты создания вовсе.
Вот то, что у меня в результате получилось:
/// <summary>
/// Gets a value indicating whether or not the post is visible or not.
/// </summary>
public bool IsVisible
{
get
{
if (this.IsDeleted)
return false;
else if (this.IsPublished)
return true;
else if (Security.IsAuthorizedTo(Rights.ViewUnpublishedPosts))
return true;
return false;
}
}
/// <summary>
/// Gets a value indicating whether a post is available to visitors not logged into the blog.
/// </summary>
public bool IsVisibleToPublic
{
get
{
return this.IsPublished && !this.IsDeleted;
}
}
Заключение
Пере-собрав всё это дело и заново загрузив BlogEngine.Core.dll на сервер, проблема была успешно решена.И
отображаться стали все опубликованные и не удалённые посты.Ссылки
Всем спасибо за внимание и хорошей Вам жизни !
До новых встреч.