Microsoft User Group Винница feedback ASP.NET MVC 2: Необязательные URL-параметры - Разработка приложений - Microsoft User Group Винница

 

ASP.NET MVC 2: Необязательные URL-параметры

Если у вас объект модели имеет свойство Id, то вы столкнетесь с проблемой, когда состояние модели будет невалидным при связывании с этой моделью, даже когда у вас отсутствует поле "Id" в форме.

Следующая ситуация более понятно объяснит к чему я клоню. Предпологается, что у вас есть модель с двумя свойствами.

public class Product {
    public int Id { get; set; }
    public string Name { get; set; }
}

Добавляете представление для создания нового Product. Вы конечно же не хотите, чтобы пользователь задавал Id.

<% using (Html.BeginForm()) {%>
 
  <fieldset>
    <legend>Fields</legend>
 
 
    <div class="editor-label">
      <%= Html.LabelFor(model => model.Name) %>
    </div>
    <div class="editor-field">
      <%= Html.TextBoxFor(model => model.Name) %>
      <%= Html.ValidationMessageFor(model => model.Name) %>
    </div>
 
    <p>
      <input type="submit" value="Create" />
    </p>
  </fieldset>
 
<% } %>

 

Метод действия выглядит так:

[HttpPost]
public ActionResult Index(Product p)
{
    if (!ModelState.IsValid) {
        throw new InvalidOperationException("Modelstate not valid");
    }
    return View();
}

Вы обнаружите, что состояние модели невалидно. В чем же причина? Проблема в том, что свойство Id, объекта Product устанавливается, как пустая строка. Почему же так происходит, когда поле Id не присутствует в форме? Ответ, друзья мои, прост - всему виной маршрутизация.

Если открыть свеже-созданный проект ASP.NET MVC 1.0, то можно увидеть объявление маршрутизатора по умолчанию

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = "" }
);

Напомню, в проекте имеется маршрутизатор с тремя URL-параметрами (controller, action, id), каждые имеет значение по умолчанию ("home", "index", "").

Соответственно, если вы будете отсылать данные формы по адресу /Home/Index, без указания "ID" в URL, то маршрутизатор подставит пустую строку для ключа "id". Теперь нам ясно, что используются значения маршрутизатора для связки с параметрами метода действия.

В итоге, случилась "накладка", когда свойство вашего объекта модели "Id", имееет точно такое же имя, как и у параметра маршрутизатора, а модель привязки пытается присвоить значению свойства Id пустую строку. Но Id является целым числом не равное null, соответственно у нас возникает ошибка приведения типов.

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

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

Начиная с ASP.NET MVC 2 RTM версии, стандартный шаблон проекта будет с измененным видом роутера.

Источник - Phil Haack


Поділитись


Related Posts with Thumbnails Posted фев 13 2010, 03:44 by Евгений Жарков View 1 350 1
Filed under: ,

Comments

R on 04-18-2010 12:36

В ASP.NET MVC 2 эта проблема решается за счет дефолтных значений параметров

Add a Comment

(required)  
(optional)
(required)  
Remember Me?
Please add 8 and 3 and type the answer here:

Enter captcha:

Информация

О нас
Timeline
Спонсоры
Поддержать

Разделы

Блоги
Медиа
Форумы
Вики
Презентации

Работа

Вакансии
Компании

Проекты

TechPosters
Data Mining SDK
Численные методы на C#
iPhoner
Data Extracting SDK

Контакты

msugvn@gmail.com
krakovetsky.alex
@msugvnua
ВКонтакте
LinkedIn
Facebook
INETA

Разработка логотипа: Helen

Статистика

Powered by Community Server (Non-Commercial Edition), by Telligent Systems