开发者

How to decouple relational MVC data

开发者 https://www.devze.com 2023-03-06 14:17 出处:网络
Consider this Scenario: I want to build an MVC application for Northwind Database. I want to have a view that list some orders and I want to create links for CustomerID and EmployeeID and a details l

Consider this Scenario:

I want to build an MVC application for Northwind Database. I want to have a view that list some orders and I want to create links for CustomerID and EmployeeID and a details link for [OrderDetails] so that when a user clicks any of these links related data will appear in the same page.

My problem is how to decouple this data that is interrelated into views and controllers that show related data in a page, and controllers responsible for individual parts of the information.

Also, how do I configure routing for this sample?

<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>

and Order Details partial view:

<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>

global.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
        开发者_如何学Python);
    }

Given this structure; how I can display order details under the order list when any of the OrderDetails links are clicked?

And, why is the URL displayed like this when I click on OrderDetails links:

http://localhost:49444/NorthwindOrders/GetOrderDetails?id=10250

I want the URL to display this way:

http://localhost:49444/NorthwindOrders/GetOrderDetails/10250


For your routing question:

if you set up a route like so:

    routes.MapRoute(
        "orderdetails", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "NorthwindOrders", action = "GetOrderDetails", id = UrlParameter.Optional, CustomerID = UrlParameter.Optional } // Parameter defaults
    );

It will build the URL in the fashion you're wanting.

(Alternatively, you can rename the parameter to your GetOrderDetails action to string OrderId and it will find the route that formats the URL the way you want it.)

As far as your main question:

How do I 'dynamically' load content on the page based on clicks to links?

There are two ways to approach this:

  • Post back pages.
  • AJAX / Dynamic loading of data and elements in the HTML on your page.

In the post-back scenario:

In this scenario your links would all go to actions that build a model that includes the orderlist from your main page, and for the details of the specific order you clicked you'd populate your model with specifics for that order. Then your ActionResult return is the same view (or one that looks the same at least), and your view would use the PartialView Html helper to render the details.

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);
}
...

In the Ajax scenario:

The Ajax scenario is essentially the same except that you hide the server round-trip in an ajax call, and then reload the page, or just a div with the content you want from the html (or JSON) in the return data of the ajax call.

The advantage of the Ajax approach is that you could specify a different Action on a different Controller for the various parts of the page you wanted to update.


Nima,
you can do it via partial views or render action, and json to display data
the basic example is as example here: http://www.asp.net/mvc/tutorials/iteration-7-add-ajax-functionality-cs

or very popular option is display action for the task in jquery.dialog()

depends on you what way you want to proceed cpo


revised:

My bad. From logic point of view, it is as this:
It depends only on you, which way you want to go. (From my point of view)

Benefits of separating the logic is :

  1. simple to understand as controller is related only to actions for eg: orders
  2. Can be used on more places if you need
  3. Easy to test only small items, eg one testcase/fixture to controller for only orders
  4. Usefull for more complicated projects

On the other hand

  1. Keep everything in one controller and split the logic by regions
  2. Eveything is together, easy to see other methods and what they do

Hope this is what you were looking for
cpo

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号