среда, 30 сентября 2015 г.

Про using или знаете ли вы что...

Наверняка, вы знаете что в C# есть такая конструкция, как using. И, скорее всего, в курсе, что использовать его можно и нужно только с объектами, реализующими интерфейс IDisposable (и, соответственно, скорее всего, что-то делающими с неуправляемыми ресурсами). На всякий случай, напомню, что конструкция вида:

 
using (someType obj = new someType())
{
         //тут что-то происходит
}
разворачивается компилятором вот в такую:

 
someType obj = new someType();
try
{
        //тут что-то происходит
}
finally
{
        //если объект значимого типа (value-type)
        ((IDisposable)obj).Dispose();

        //или, если объект ссылочного типа (reference-type)
        if (obj!=null)
           ((IDisposable)obj).Dispose();
}
а где же блок catch, спросите вы? Почему его нет? И почему не предусмотрен вариант using, где его можно задать?


среда, 25 марта 2015 г.

Как в .Net получить действительно случайные числа

Наверняка, всем известно о существовании в .Net класса System.Random, позволяющего получать якобы случайные числа практически без особых как умственных, так и временных затрат. Представьте что у нас есть такой вот метод, который чисто ради эксперимента мы вызовем в цикле несколько раз:

        
        static string GetRandomNum(int minValue, int maxValue)
        {
            Random rnd = new Random();
            return rnd.Next(minValue, maxValue).ToString();
        }

        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine(GetRandomNum(1,11));
        }


В данном случае вы получите совершенно одинаковые все "случайные" цифры.

Происходит так потому, что при инициализации объекта Random с использованием конструктора по умолчанию в качестве числа, использующегося для вычисления случайных чисел используется Environment.TickCount (количество миллисекунд, прошедших со времени старта системы), который обновляется раз в 15.6 миллисекунд.


четверг, 12 марта 2015 г.

Используем сессию в обработчиках (HTTP handlers) ASP.NET

Представьте себе гипотетическую ситуацию, когда вам нужно отдавать пользователю файлы, с, допустим, какими-то индивидуальными для каждого пользователя данными, причем именно отдавать уже готовые файлы, а не генерировать на лету. Самым простым и очевидным вариантом было бы создать обработчик, который будет вызываться для запросов вида "*_report.pdf", но для этого нам нужно понимать, можно ли отдавать пользователю файл, который он запрашивает или он принадлежит другому пользователю.
Передавать идентификатор в явном виде не только не правильно идеологически, но и просто не красиво, да и сохраненный файл, полученный по ссылке вида 10102_u323467_report.pdf?sessId=05446DA8F736B29A будет по умолчанию сохранен с таким же "кривым" именем.

Значительно проще положить этот идентификатор в сессию и получать его в обработчике уже оттуда. Для того, чтобы объект Session был доступен, нам нужно, чтобы обработчик наследовал не только от интерфейса IHttpHandler, но од одного из интерфейсов IRequiresSessionState или IReadOnlySessionState в зависимости от того нужен ли нам доступ только на чтение (IReadOnlySessionState) или на чтение и запись (IRequiresSessionState). На самом деле, записать в объект сессии вы сможете что угодно в любом случае, единственное отличие, что при использовании IReadOnlySessionState в конце обработки запроса данные сессии не сохраняются.


среда, 11 марта 2015 г.

Как сделать поля ввода с "подсказками" с помощью jQuery и CSS

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


В принципе, все современные браузеры, поддерживают стандарт HTML5 и, соответственно, атрибут placeholder, которой для этой цели и был придуман. Проблема в том, если вам необходима поддержка старых браузеры или чуть менее старые версии Internet Explorer (который начал поддерживать этот атрибут только в 10 версии), то подсказку созданную с помощью него они не увидят.
Если вы используете на своем сайте jQuery, то есть простое и быстрое решение для создания таких полей буквально несколькими строчками кода.  Прежде всего нужно создать стиль отображения "подсказок":

<style type="text/css">
    .helpField { background:white; }
    .blankHelpFieldText { color: #a1a1a1; font-style: italic; }
</style>


При этом, первый стиль несет в себе единственное практическое предназначение - быть "свойством" к которому будет привязываться скрипт отображения текста подсказки. Так что, вместо background можете написать что вам больше подходит, например width.


четверг, 5 февраля 2015 г.

Как победить ошибку "The SDDL string contains an invalid sid..." при установке SharePoint 2013

Я уже два раза при установке SharePoint Server 2013 сталкивался c возникновение странной ошибки "The SDDL string contains an invalid sid or a sid that cannot be translated" или "Строка SDDL содержит недопустимый sid либо sid, который не может быть преобразован." для русскоязычной версии. Выглядит момент появления ошибки вот так:


Как это часто периодически бывает с продуктами Microsoft текст ошибки никак не намекает ни то что на решение проблемы, но даже на то в какую сторону надо смотреть.


воскресенье, 11 января 2015 г.

Делаем локализацию сайта на ASP.NET MVC

Представьте, что вы решили делать сайт с использованием ASP.NET MVC. И, помимо всего прочего, вам на этом сайте вам нужна возможность отображения его на нескольких языках. Задача, хоть и кажущаяся с первого взгляда не самой тривиальной, на самом деле, достаточно проста. И я сейчас расскажу что для этого нужно сделать.


Во-первых, необходимо как-то передавать идентификатор языка. Можно, конечно, придумать какое-нибудь извращение, типа хранения текущего языка в сессии, но лучше всего просто передавать его в URL. Как минимум, в это случае, локализованными ссылками на ваш сайт можно будет без проблем делиться, хоть в соцсеятх, хоть пересылать их по e-mail. 
Для этого в вашем проекте открываем файл RouteConfig.cs, находящийся в папке App_Start и добавляем туда путь для локализованного  контента.
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                name: "Localization",
                url: "{lang}/{controller}/{action}/{id}",
                defaults: new { lang = "ru", controller = "Home", action = "Index", id = UrlParameter.Optional },
                //ограничение необходимо, чтобы отличить параметр языка от параметра контроллера. 
                //В данном случае, в качестве параметра lang подходят все двухсимвольные комбинации из букв латинского алфавита, например "en" или "fr"
                constraints: new { lang = @"[a-z]{2}" }
            );

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }           
            );
        }

Теперь, если в URL содержится идентификатор языка, то он будет приходить нам в коллекции RequestContext.RouteData, и получить его проще всего в методе в методе Initialize контроллера. Давайте для простоты сделаем локализованную страничку авторизации, которая будет отображаться сразу же при входе на сайт, то есть по пути /.