Передача данных из контроллера в представление пользовательского управления с помощью ASP.NET MVC
-
03-07-2019 - |
Вопрос
У меня есть класс представления (OrderView.aspx), который показывает сведения о заказе (имя учетной записи, дату заказа), а также список строк заказа через элемент управления Повторитель.Каждая строка заказа представлена пользовательским представлением управления (OrderLineView.ascx), в котором отображаются сведения о строке заказа (название позиции, количество, цена).У меня есть объект модели под названием Order, который я использую в качестве источника данных для всего этого и передаю его как объект модели для представления.
Каждый пользовательский элемент управления OrderLineView имеет кнопки «Сохранить» и «Удалить».У меня есть кнопка «Сохранить», отправляющая содержимое формы внутри элемента управления OrderLine в метод Save на контроллере, а затем RedirectToAction обратно на ту же страницу заказа (при этом обновляется вся страница, в этом нет ничего AJAXy).У меня есть кнопка «Удалить», ссылающаяся на метод контроллера, который пытается удалить, а затем RedirectToAction обратно на ту же страницу заказа.Однако, если удаление не удалось, я хочу, чтобы рядом с кнопкой удаления отображалось небольшое сообщение об ошибке, когда страница снова отображается (помните, что для каждой строки заказа на странице есть кнопка удаления, поэтому мне нужно только сообщение рядом с тот, который я нажал).Мои вопросы:
1. Как передать эти данные из метода контроллера в конкретный пользовательский элемент управления?Стоит ли как-то добавить это в модель?Кажется плохой идеей (поскольку это действительно не часть модели).
2. Должен ли я иметь OrderLineController для операций OrderLine, а также OrderController для операций Order?Я просто хочу знать, лучше ли использовать отдельный контроллер для каждого представления.
3. Я видел, как некоторые люди могут вызывать RedirectToAction со значением анонимного типа, например:
RedirectToAction("ViewOrder", new { Id = 1234, Message = "blabla"});
но это приводит к тому, что значение сообщения отображается в строке URL.Меня это устраивает, но я бы предпочел, чтобы это не показывалось, если это возможно.
4. Кроме того, для доступа к свойствам модели из представления я постоянно делаю это:
foo(((someModelType) this.ViewData.Model).SomeProperty);
Мне это не нравится по ряду причин, одна из которых заключается в том, что я не хочу, чтобы мое представление было связано с типом моей модели (именно поэтому я использую ViewPage вместо ViewPage).Я бы предпочел иметь возможность звонить так:
foo(ModelEval("SomeProperty"));
Что-то подобное существует?Я написал свою собственную, но мне бы хотелось, чтобы это не было необходимостью.
Решение
1
Посмотрите МодельСтат.
ViewData.ModelState.AddModelError("something.Name", "Please enter a valid Name");
ModelState на самом деле представляет собой словарь, поэтому вы можете идентифицировать ошибки для каждого элемента управления.Я не знаю, является ли это лучшей практикой, но, вероятно, это сработает.Попробуйте что-нибудь в духе
ViewData.ModelState.AddModelError("something#3.Name", "Please enter a valid Name");
и, по вашему мнению, вы могли бы поставить
<%= Html.ValidationMessage(string.format({"something{0}.Name", YourUniqueId))%>
4
Вы можете строго типизировать свое представление, поэтому вам не понадобится это приведение, но если вас беспокоит тесная связь, это может вас отпугнуть.Но наличие сильного типа в любом случае не более тесно связано, чем наличие волшебной строки, указывающей на это свойство модели.Первый просто дает вам безопасность типов и славу intellisense.
Другие советы
Поскольку ваша OrderLine имеет уникальный идентификатор, вы можете использовать его для создания ключа, который будет помещен в контейнер ошибок ModelState.
public ActionResult Delete(int? Id)
{
ModelState.AddModelError("OrderLine" + Id.Value, "Error deleting OrderLine# " + Id.Value);
...
}
а затем используйте помощник ValidatinoMessage.Это проверит ModelState, чтобы увидеть, существует ли ошибка, и если да, то отобразится сообщение.В противном случае это пусто.
<%= Html.ValidationMessage ("OrderLine" + Id)%>
В следующем выпуске модели MVC модель станет свойством верхнего уровня, поэтому следующие
foo(((someModelType) this.ViewData.Model).SomeProperty);
можно записать как
foo(Model.SomeProperty);
Объекты модели уже должны быть напечатаны, если вы не используете общественный объект как собственность?