пятница, 19 августа 2011 г.

Sharing ASP.NET MVC views across multiple projects (apps)

Если ведется разработка нескольких проектов, использующих ASP.NET MVC, вполне возможна ситуация, когда появляются представления (views), или частичные представления (partial views) с идентичной функциональностью. Например, календарь для выбора даты. Но попытка получить из одного приложения доступ к ресурсам другого будет пресечена политиками безопасности (что, в принципе, разумно).

Решение проблемы копированием вовсе не подходит, так как оно затрудняет поддержку существующего кода. Другое решение, состоящее в написании своего провайдера виртуальных путей, позволяющего обойти это ограничение, больше похоже на хак, и не выглядит приемлемым.

Для решения задачи целесообразно применить возможность IIS создавать виртуальные директории. Теперь, при разворачивании (deployment) решения, необходимо создать одну физическую директорию (physical directory), содержащую общие представления (shared views), и после этого создать по виртуальной директории (virtual directory) для каждого проекта, которые будут отображаться на эту единственную физическую.

Это решение простое, не требующее особых усилий для реализации и, к тому же, не противоречащее политикам безопасности, принятым по умолчанию, поэтому, как по мне, оно хорошо подходит для использования на практике.

понедельник, 15 августа 2011 г.

IIS Restart

Опытные разработчики скорее всего знают, но все равно отмечу, что iisreset (из командной строки) работает более надежно, чем перезапуск сервера (Restart) с помощью консоли управления (IIS Management).

Таким образом, если "обычный" перезапуск из консоли управления не помогает - iisreset скорее всего решит проблему.

вторник, 2 августа 2011 г.

ASP.NET MVC, ORM, ReflectionPermission и Trust Level

Используя ORM в проекте ASP.NET MVC, который хостится на IIS, можно столкнуться с ошибкой системы безопасности вроде "System.Security.SecurityException: Request for the permission of type 'System.Security.Permissions.ReflectionPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.".

При этом приложение имеет Full Trust Level (...trust level="Full"... в конфиге, что также подтверждается, если заглянуть в консоль управления IIS).

Проблема может быть связана с текущим значением Application Pool Identity (запрет превыше разрешения) - в данном случае использование NetworkService решило проблему, так как у AppPoolIdentity отсутствовали необходимые разрешения.

воскресенье, 24 июля 2011 г.

Треугольная периодическая функция

Задача. Есть алгоритм, работающий с некоторым рядом значений. Нужно учесть периодичность следующего характера: например, 1, 2, 1, но не 1, 2, 0; значения в общем случае действительные, целочисленные использованы здесь для простоты). Т. е. нужна функция, принимающая на вход значение без учета периодичности и возвращающая корректное значение с учетом периодичности, так, чтобы возвращаемое значение принадлежало валидному диапазону.

Не сложно догадаться, что функция с указанными свойствами имеет треугольную форму - рост, спад, рост, спад и т. д.

Не буду долго тянуть - далее код, выполняющий задачу и пояснения, как он работает и почему именно так.

/*!
 Represents triangular periodic function with shape 
 {min, min}, {max, max}, {min, min} and period equal to 2*(max - min).
 Third parameter are value that needs to be bound 
 within min and max using periodic nature of function.
*/
inline float TriangularPeriodicFunction(float min, float max, float val)
{
 // shifting coordinate system so function is above x axis now
 // (and performing inverse shift when result is obtained)
 if (min < 0)
  return TriangularPeriodicFunction(0, max - min, val - min) + min;

 // function is symmetric relative to axis of values
 val = fabs(val);
 
 // length of monotonous interval (MI)
 float len = max - min;
 // index of MI
 int d = (int) floor(val/len);
 // index of value within MI
 float m = fmod(val, len); 

 if (d >= 0)
  // MI is at the right side (relative to the y axis)
  return d&1 
   ? max - m // values within MI are decreasing
   : m; // values within MI are increasing
 else
  // MI is at the left side (relative to the y axis)
  return d&1 
   ? m - max // values within MI are increasing
   : m; // values within MI are decreasing
}

Сначала производится сдвиг системы координат, так, чтобы график оказался над осью абсцисс - пример ниже. Это необходимо для однозначного определения положения интервала относительно оси значений.

До преобразования (функция с минимумом -2, максимумом 2):

После преобразования:

После этого определяется индекс монотонного интервала (МИ) с целью узнать - возрастает ли он, или убывает.

А далее все совсем просто: если МИ возрастает, то необходимо вернуть значение, взятое по модулю длины интервала (назовем его M), иначе вернуть то же значение за вычетом максимума (MAX) для интервала, находящегося слева от оси значений или разность MAX - M для интервала, находящегося справа от оси значений. В конце, если нужно, производится обратный сдвиг системы координат (первая-вторая строки кода функции).

Код протестирован и работает для действительных чисел.

четверг, 21 июля 2011 г.

Visual Studio: доверяй, но проверяй... себя!

В предыдущем посте я выразил недоверие к Visual Studio's Clean Solution. Я был не прав - нужно было проверить настройки Configuration Manager, где следует отметить все проекты, подлежащие сборке при построении билда решения.


Дело в том, что ранее я и не заглядывал в эти настройки, хотя знаком со Студией довольно давно - по умолчанию во всех решениях, с которыми доводилось работать, собирались все проекты. Но, как оказалось, в крупных решениях действительно очень удобно отключить сборку проектов, над которыми работа не ведется в данный момент - это ускорит процесс сборки для всего решения. Что же, будем знать! :)

вторник, 19 июля 2011 г.

Visual Studio: когда Clean Solution не помогает

UPD. На самом деле все ОК - подробнее в этом сообщении.

Сегодня столкнулся со странной проблемой: после внесения изменений в код проекта, использующего ASP.NET MVC, и полного ребилда сервер (для отладки использовался локальный IIS) исполнял старую версию.

Очистил решение, собрал - результат тот же, и если поставить брейкпоинт где-нибудь, то он деактивируется по причине вроде "The breakpoint will not currently be hit. The source code is different then the original version.".

Решение проще простого - вручную удалить папку bin и пересобрать проект. Почему я не применил его сразу, а потратил время на копание в настройках проекта и документации? Доверял среде, выполняя Clean Solution. Вот так - доверяй, но проверяй.

суббота, 2 июля 2011 г.

Visual Studio 2010: невозможно заново подключить System.Core.dll

Недавно столкнулся с тем, что в MSVS 2010 невозможно заново подключить System.Core.dll в проект. Оказывается, это известная проблема. Решение - добавить нужную ссылку вручную, открыв файл проекта в текстовом редакторе:
<ItemGroup>
    ...
    <Reference Include="System" />
    <Reference Include="System.Core" />
    ...
</ItemGroup>