Проблема one-click publish и MvcBuildViews в asp.net MVC

При использовании one-click publish я как-то раз столкнулся с подобной ошибкой:

It is an error to use section registered as allowDefinition=’MachineToApplication’ beyond application level. This error can be caused by a virtual directory not being configured as an application in IIS.

Происходит она при попытке компиляции проекта после первого же паблиша (на удаленный сервер или даже в локальную папку).
Столкнувшись сегодня с ней во второй раз и осознав, что я не помню, «что это было» и как это лечится, решил написать заметку.
Continue reading

Хитрость байндинга булевых полей в asp.net mvc

Сегодня мне вдруг стало любопытно, как происходит байндинг булевых полей в MVC.
Причину любопытства можно пояснить на примере:
Допустим, у нас есть модель:

public class TestModel {
   public string Name {get;set;}
   public bool IsDeleted {get;set;}
}

И есть две хтмл-формы для редактирования этой модели, в первой из которых присутствует флаг IsDeleted, а во второй — нет:
Форма 1:

@using (Html.BeginForm) {
    @Html.TextboxFor(x => x.Name)
    @Html.CheckboxFor(x => x.IsDeleted)
    <input type="submit" value="OK" />
}

Форма 2:

@using (Html.BeginForm) {
    @Html.TextboxFor(x => x.Name)
    <input type="submit" value="OK" />
}

При этом серверный обработчик этой формы выглядит вполне типично:

public ActionResult UpdateModel(int id) {
  var model = Db.Load<TestModel>(id);
  TryUpdateModel(model);
  return RedirectToAction();
}

Предположим, что в базе у TestModel IsDeleted == true. Что произойдет, если

  • мы отсабмитим Форму1 со снятым флагом?
  • мы отсабмитим Форму2, в которой флага IsDeleted просто нет?

Как и ожидалось, в обоих случаях MVC отработал отлично, и в случае 1 в базе у сущности TestModel поле IsDeleted стало false, а в случае 2 — осталась в true.
В чем же причина любопытства? Мне было любопытно, как же именно это работает.
В «классическом html» чекбоксы обычно представлены в виде <input name=’IsDeleted’ type=’checkbox’ />. А при сабмите формы на сервер это отправляется в виде:

  • http://localhost/?name=zcx&IsDeleted=on — если флажок проставлен
  • http://localhost/?name=zcx — если флажок не стоит

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

Именно поэтому мне было интересно заглянуть «под капот» и узнать, как же это реализовано в mvc3.
Решение оказалось простым: на каждое булево поле mvc генерит такой html:

<input type="checkbox" name="IsDeleted" value="true" /><input type="hidden" name="IsDeleted" value="false" />

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