#asp.net-mvc #asp.net-mvc-3 #asp.net-mvc-routing
#asp.net-mvc #asp.net-mvc-3 #asp.net-mvc-routing
Вопрос:
Рассмотрим этот сценарий:
Я хочу создать MVC-приложение для базы данных Northwind. Я хочу иметь представление, в котором перечислены некоторые заказы, и я хочу создать ссылки для CustomerID и EmployeeID и ссылку details для [OrderDetails], чтобы, когда пользователь нажимает на любую из этих ссылок, связанные данные отображались на той же странице.
Моя проблема заключается в том, как разделить эти данные, которые взаимосвязаны, на представления и контроллеры, которые отображают связанные данные на странице, и контроллеры, ответственные за отдельные части информации.
Кроме того, как мне настроить маршрутизацию для этого примера?
<table width="500px">
<tr>
<th></th>
<th>
OrderID
</th>
<th>
CustomerID
</th>
<th>
EmployeeID
</th>
<th>
OrderDate
</th>
<th>
RequiredDate
</th>
<th>
ShippedDate
</th>
<th>
ShipVia
</th>
<th>
OrderDetails
</th>
</tr>
<% foreach (var item in Model) { %>
<tr>
<td>
<%: Html.ActionLink("Edit", "Edit", new { id=item.OrderID }) %> |
<%: Html.ActionLink("Details", "Details", new { id=item.OrderID })%> |
<%: Html.ActionLink("Delete", "Delete", new { id=item.OrderID })%>
</td>
<td>
<%: item.OrderID %>
</td>
<td>
<%: item.CustomerID %>
</td>
<td>
<%: item.EmployeeID %>
</td>
<td>
<%: String.Format("{0:g}", item.OrderDate) %>
</td>
<td>
<%: String.Format("{0:g}", item.RequiredDate) %>
</td>
<td>
<%: String.Format("{0:g}", item.ShippedDate) %>
</td>
<td>
<%: item.ShipVia %>
</td>
<td>
<%: Html.ActionLink("OrderDetails", "GetOrderDetails", new { id = item.OrderID })%>
</td>
</tr>
<% } %>
</table>
<p>
<%: Html.ActionLink("Create New", "Create") %>
</p>
<div>
<p>
<% Html.RenderPartial("GetOrderDetails"); %>
</p>
<%--<uc1:GetOrderDetails ID="GetOrderDetails1" runat="server" />--%>
</div>
и частичный просмотр деталей заказа:
<table>
<tr>
<th></th>
<th>
OrderID
</th>
<th>
ProductID
</th>
<th>
UnitPrice
</th>
<th>
Quantity
</th>
<th>
Discount
</th>
</tr>
<% foreach (var item in Model) { %>
<tr>
<td>
<%: Html.ActionLink("Edit", "Edit", new { id=item.OrderID }) %> |
<%: Html.ActionLink("Details", "Details", new { id=item.OrderID })%> |
<%: Html.ActionLink("Delete", "Delete", new { id=item.OrderID })%>
</td>
<td>
<%: item.OrderID %>
</td>
<td>
<%: item.ProductID %>
</td>
<td>
<%: String.Format("{0:F}", item.UnitPrice) %>
</td>
<td>
<%: item.Quantity %>
</td>
<td>
<%: item.Discount %>
</td>
</tr>
<% } %>
</table>
<p>
<%: Html.ActionLink("Create New", "Create") %>
</p>
глобальный.asax:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default2", // Route name
"{controller}/{action}/{OrderId}/{CustomerID}", // URL with parameters
new { controller = "NorthwindOrders", action = "Index", OrderId = UrlParameter.Optional, CustomerID = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
Учитывая эту структуру; как я могу отобразить детали заказа в списке заказов при нажатии на любую из ссылок OrderDetails?
И почему URL отображается таким образом, когда я нажимаю на ссылки OrderDetails:
http://localhost:49444/NorthwindOrders/GetOrderDetails?id=10250
Я хочу, чтобы URL отображался таким образом:
http://localhost:49444/NorthwindOrders/GetOrderDetails/10250
Комментарии:
1. Еще не поздно попытаться решить это в представлении. Разве вы не должны были решить это раньше, в контроллере. Представление просто отображает данные, поэтому при правильной модели или даже viewmodel представление становится тривиальной интерпретацией.
Ответ №1:
На ваш вопрос о маршрутизации:
если вы настроили маршрут следующим образом:
routes.MapRoute(
"orderdetails", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "NorthwindOrders", action = "GetOrderDetails", id = UrlParameter.Optional, CustomerID = UrlParameter.Optional } // Parameter defaults
);
Он создаст URL-адрес так, как вы хотите.
(В качестве альтернативы, вы можете переименовать параметр вашего действия GetOrderDetails в string OrderId
, и он найдет маршрут, который форматирует URL так, как вы хотите.)
Что касается вашего основного вопроса:
Как мне «динамически» загружать содержимое на страницу на основе переходов по ссылкам?
К этому можно подойти двумя способами:
- Опубликовать предыдущие страницы.
- AJAX / Динамическая загрузка данных и элементов в HTML на вашу страницу.
В сценарии обратной отправки:
В этом сценарии все ваши ссылки будут вести к действиям, которые создают модель, включающую список заказов с вашей главной страницы, и для получения подробной информации о конкретном заказе, который вы нажали, вы бы заполнили свою модель спецификациями для этого заказа. Тогда ваш ActionResult возвращает тот же вид (или, по крайней мере, тот, который выглядит одинаково), и ваш вид будет использовать HTML-помощник PartialView для отображения деталей.
OrderViewModel:
public class OrderViewModel
{
public IList<Order> Orders {get;set;}
public OrderDetail Details {get;set;}
}
OrderView.aspx:
<%@ Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage<OrderViewModel>" %>
<%:Html.DisplayFor(m=>m.Orders)%> <%-- Displays the Table above listing orders --%>
<%:Html.DisplayFor(m=>m.Details)%> <%-- Displays your custom view of the details --%>
OrderController:
...
public ActionResult List()
{
var model = new OrderViewModel { Orders = GetAllOrders(), Details = null };
return View("OrderView", model);
}
public ActionResult GetOrderDetails(string OrderId)
{
var model = new OrderViewModel { Orders = GetAllOrders(), Details = GetOrder(OrderId) };
return View("OrderView", model);
}
...
В сценарии Ajax:
Сценарий Ajax по сути тот же, за исключением того, что вы скрываете обход сервера в вызове ajax, а затем перезагружаете страницу или просто div с нужным содержимым из html (или JSON) в возвращаемых данных вызова ajax.
Преимущество подхода Ajax заключается в том, что вы могли бы указать другое действие на другом контроллере для различных частей страницы, которые вы хотели обновить.
Комментарии:
1. Спасибо, но как я могу загрузить детали на той же странице?H
2. Не видя вашего контроллера (ов) и модели (ов), трудно сказать… Вы можете сделать это либо с помощью AJAX, либо с помощью post-backs… Я расширю свой ответ.
3. спасибо, но мой главный вопрос remain.in полученное нами представление наследуется=»System.Web.Mvc.ViewPage<IEnumerable<My_MVC_Samples. Модели. Порядок>>» и это говорит нам, от какого объекта зависит наше представление. хорошо, как мы можем показать детали заказа (объект OrderDetails) в представлении, которые наследуются от объекта Order?
4. В вашей модели может быть как свойство Order, так и свойство OrderDetails. Или, если вы сделали это с помощью javascript и ajax, вы могли бы забыть Модель для деталей заказа и просто создать детали из JSON-представления модели details.
5. Я не хочу использовать Ajax. Я думаю, что с помощью Ajax мы обходим проблему, а не решаем ее. Можете ли вы показать мне короткий пример того, что вы говорите?
Ответ №2:
Nima,
вы можете сделать это с помощью частичных представлений или действия рендеринга и json для отображения данных
основной пример приведен здесь:http://www.asp.net/mvc/tutorials/iteration-7-add-ajax-functionality-cs
или очень популярный вариант — отобразить действие для задачи в jquery.dialog()
зависит от вас, каким способом вы хотите выполнить cpo
исправлено:
Виноват. С точки зрения логики, это как:
Это зависит только от вас, каким путем вы хотите пойти. (С моей точки зрения)
Преимущества разделения логики заключаются в :
- легко понять, поскольку контроллер связан только с действиями, например, для заказов
- Может использоваться в большем количестве мест, если вам нужно
- Легко тестировать только небольшие элементы, например, один тестовый набор / приспособление для контроллера только для заказов
- Полезно для более сложных проектов
С другой стороны
- Храните все в одном контроллере и разделите логику по регионам
- Все собрано вместе, легко увидеть другие методы и то, что они делают
Надеюсь, это то, что вы искали
cpo
Комментарии:
1. Спасибо, но моя проблема в том, как отделить контроллеры и просмотр.
2. Вы не можете просто добавить форму вокруг объекта, который хотите отобразить, и опубликовать в разных местах? например, Html.BeginForm (спецификация вашего маршрута здесь)
3. Я думаю, вы неправильно поняли мой вопрос. Я хочу знать, должен ли я создать контроллер для заказов, Customers и OrderDetails?
4. смотрите мой пересмотренный ответ (надеюсь, я знаю, что вы ищете сейчас :))