Здравствуйте друзья, коллеги.
Вступление
Недавно решил создать свой блог. Поскольку я долгое время являюсь .NET разработчиком, мой выбор пал на один из немногих бесплатных .NET движков для создания блогов: Blog Engine .NET. Многие критикуют такой подход: мол блог не для того, что бы его "допиливать", а для того что бы писать посты.
Я придержуюсь другой точки зрения. Очень часто используя софт мне не хватает той или иной функции и очень круто по моему скромному мнению, когда есть возможность добавить (исправить) необходимую функцию. Вместо того, что бы ждать и надеяться: "А вдруг в очередном апдейте это исправят ?".
Так вот, скачав архив с уже собранным движком, я запустил его под IIS Express:
iisexpress.exe /path:"D:\Dev\www.rostislav.nikitin.blogengine.net"
Всё настроил, добавил пару постов и решил всё это дело где-то захостить.
Мой выбор пал на 60ти дневный SmarterASP.NET триал. Мой выбор был не случаен. Мне уже доводилось пользоваться этим хостингом и я на тот момент остался вполне доволен.
Итак, зарегестрировавшись (пришлось снова зарегистрироваться, что бы получить триал ещё раз) и загрузив приложение с на сервер, я был неприятно удивлён.
Проблема
При открытии главной страницы не было видно ни одного
поста, хотя их там должно было быть два - я добавлял их ещё в локальной версии
блога и в последствии успешно загрузив всю папку с локальным
блогом на сервер.
Однако я заметил что в разделе "AuthorList" было видно что таки в системе есть два
поста:
![](data:image/png;base64,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)
Это говорило о том, что они есть где то в системе, но почему то не отображаются на главной странице.
Повозившись немного я бросил это дело т.к. уже было поздно и хотелось спать. Было предчувствие, что это проблема кеширования.
Что интересно так это то, что на следующий день, зайдя на сайт, оба поста были на первой странице. Но внутренняя интуиция подсказывала - баг всё ещё здесь :) Поэтому, добавив пару тестовых постов я убедился, что интуиция меня не подвела - только что добавленных постов на странице не было.
Появилась мысль что проблема не в кешировании, а в чём то связанном со временем. 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 на сервер, проблема была успешно решена.И
отображаться стали все опубликованные и не удалённые посты.Ссылки
Всем спасибо за внимание и хорошей Вам жизни !
До новых встреч.