26. December 2010 · 1 comment · Categories: Misc

Как оказалось, вставить код прямо из студии вполне возможно. Достаточно установить Visual Studio Power Tools. После этого код вполне нормально вставляется в Live Writer. Вот только отображается он в wordpress в одну строчку. Для нормального отображения нужно отредактировать wp-includes/default-filters.php, закомментировать строку:

add_filter( ‘the_content’, ‘wpautop’            );

Строчка встречается несколько раз. Комментировать нужно ту, что находится в секции Display Filters:

// Display filters
add_filter( ‘the_title’, ‘wptexturize’   );
add_filter( ‘the_title’, ‘convert_chars’ );
add_filter( ‘the_title’, ‘trim’          );

add_filter( ‘the_content’, ‘wptexturize’        );
add_filter( ‘the_content’, ‘convert_smilies’    );
add_filter( ‘the_content’, ‘convert_chars’      );
// add_filter( ‘the_content’, ‘wpautop’            ); <———-
add_filter( ‘the_content’, ‘shortcode_unautop’  );
add_filter( ‘the_content’, ‘prepend_attachment’ );

После использования автоапдейта фикс, возможно, придется повторить.

Осталось выяснить, почему в Word код вставляется с 10-м размером шрифта, а в Live Writer – с 12-м.

…В примерах этого нет, но читатель легко это реализует сам…
ulu, статья на хабре 

Недавно пришлось реализовывать тот самый “smart way” отображения выпадающий списков, с поправкой на ASP.NET MVC 3. Это пост – короткий чеклист для реализации.

Попробуем отобразить выпадающий список для нескольких полей модели.

Основная модель:

ModelsMovie.cs

public class Movie
{
   
public int Id { get; set
; }
   
public int GenreId { get; set
; }
   
public int Year { get; set; }
}

Контроллер с двумя действиями – отображение формы и создание Movie:

ControllersMovieController.cs

public class MovieController : Controller
{
    [
HttpGet
]
   
public ActionResult
Create()
    {
       
return
View();
    }

    [
HttpPost
]
    [
ActionName("Create"
)]
   
public ActionResult CreateMovie(Movie
model)
    {
       
if (!this
.ModelState.IsValid)
        {
           
return
View(model);
        }
       
else
        {
           
// TODO: save model
            // this.Repository.Save(model);

           
return this.RedirectToAction("Details"
,
               
new
{ id = model.Id });
        }
    }

    [
HttpGet
]
   
public ActionResult
Details()
    {
       
// sample code to show the same Create form with preset values
        return View("Create", new Movie() { GenreId = 2, Year = 2000 });
    }
}

Представление для создания Movie. Создано стандартным scaffold-ом. Подключение скриптов валидации перенесено в Views/Shared/_Layout.cshtml:

ViewsMovieCreate.cshtml

@model MvcDropDowns.Models.Movie

@{
    ViewBag.Title =
"Create a Movie"
;
}

<h2>Create a Movie</h2>

@
using
(Html.BeginForm()) {
    @Html.ValidationSummary(
true
)
   
<fieldset>
        <legend>Movie</legend>

       
<div class="editor-label">
            @Html.LabelFor(model => model.GenreId)
       
</div>
        <div class="editor-field">
            @Html.EditorFor(model => model.GenreId)
            @Html.ValidationMessageFor(model => model.GenreId)
       
</div>

       
<div class="editor-label">
            @Html.LabelFor(model => model.Year)
       
</div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Year)
            @Html.ValidationMessageFor(model => model.Year)
       
</div>

       
<p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

Собираем, запускаем. Видим два текстовых поля. При нажатии на кнопку Create срабатывают клиентские валидаторы – поля не nullable.

image

Начнем превращать текстбоксы в выпадающие списки. Для начала, добавим UIHint и еще пару атрибутов для более человеческого отображения:

ModelsMovie.cs

public class Movie
{
   
public int Id { get; set
; }
       
    [
UIHint("Genre"
)]
    [
Display(Name="Genre"
)]
    [
DisplayFormat(NullDisplayText="---Please Select---"
)]
   
public int GenreId { get; set
; }

    [
UIHint("Year"
)]
    [
DisplayFormat(NullDisplayText="---Please Select---"
)]
   
public int Year { get; set; }
}

Следующий шаг – добавление шаблонов редактирования, с именами Genre и Year:

ViewsSharedEditorTemplatesGenre.cshtml

@model int?
@{
    Html.RenderAction(
"Genres", "List");
}

ViewsSharedEditorTemplatesYear.cshtml

@model int?
@{
    Html.RenderAction(
"Years", "List");
}

Единственное назначение этих шаблонов – вызов соответствующего действия контроллера List. Все остальное, включая имена полей, контроллер в состоянии получить самостоятельно. Основной соблазн при реализации – захардкодить название полей, или часть метаданных. Постараемся этого не допустить :)

ControllersListController.cs

public class ListController : Controller
{
   
public ActionResult
Genres()
    {
       
int? selectedGenreId = this.ControllerContext.ParentActionViewContext.ViewData.Model as int
?;

       
var genres = new List<Genre
>
        {
           
new Genre { Id = 1, DisplayName = "Comedy"
},
           
new Genre { Id = 2, DisplayName = "Horror"
},
           
new Genre { Id = 3, DisplayName = "Documentary"
}
        };

       
var model = new SelectList(genres, "Id", "DisplayName"
, selectedGenreId);

       
this
.ViewData.Model = model;
       
this.ViewData.ModelMetadata = this
.ControllerContext.ParentActionViewContext.ViewData.ModelMetadata;

       
return View("DropDown"
);
    }

   
public ActionResult
Years()
    {
       
int? selectedYear = this.ControllerContext.ParentActionViewContext.ViewData.Model as int
?;

       
var model = new SelectList(Enumerable
.Range(1990, 20), selectedYear);

       
this
.ViewData.Model = model;
       
this.ViewData.ModelMetadata = this
.ControllerContext.ParentActionViewContext.ViewData.ModelMetadata;

       
return View("DropDown");
    }
}

Последний этап – добавление представления DropDown. Вызываем Html.DropDown, передавая ему все подряд:

ViewsListDropDown.cshtml

@model SelectList
@{
   
var templateInfo = this
.ViewContext.ParentActionViewContext.ViewData.TemplateInfo;
}
@
Html.DropDownList(
    templateInfo.GetFullHtmlFieldName(
""
),
   
this
.Model,
   
this
.ViewData.ModelMetadata.NullDisplayText,
   
new
    {
        id = templateInfo.GetFullHtmlFieldId(
"")
    })

После запуска мы должны увидеть полноценные выпадающие списки:

image

У предложенной реализации есть один серьезный баг. Серверные валидаторы работают (как и раньше). Клиентские – не работают совсем. О том, как их починить, рассказано во второй части.

Исходный код к этой статье: MvcDropDowns.zip. Требует ASP.NET MVC 3.0 RC2 для запуска.

Между двумя методами работы с транзакциями есть одно незаметное, очень существенное отличие.

SqlConnection.BeginTransaction создает транзакцию с уровнем изоляции по умолчанию – обычно это READ COMMITTED или READ COMMITTED SNAPSHOT.

Попытка выполнить команду в TransactionScope так же приводит к созданию транзакции SQL, но уже с уровнем изоляции SERIALIZABLE.

Внезапная разница между уровнями изоляции обеспечивает неповторимые ощущения при разрешении дедлоков :) Будьте бдительны!

01. December 2010 · 1 comment · Categories: Misc

По умолчанию с Live Writer 2011 поставляется только английский spellchecker. Русский можно до установить вручную:

1. Найти и установить Microsoft Office 2007 или 2010. Если офис английский – доустановить на него Russian Language Pack.

2. Скопировать файлы MSSP7RU.DLL и MSSP7RU.LEX из папки C:Program FilesMicrosoft OfficeOffice14PROOF в C:Program FilesWindows LiveWriterDictionaries. Для 2007-го офиса путь может немного отличаться.

3. Запустить Live Witer и сменить Dictionary Language в настройках.

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