基于数据存储值的ASP.NET MVC路由

时间:2009-12-23 13:44:25

标签: asp.net asp.net-mvc database routing

你会如何解决这个问题:

我的数据存储中有数据。每个项目都包含以下信息:

  • URL =将与请求一起使用的任意数量的第一个路段
  • 某些项目类型=显示将与此类型相关(请继续阅读)
  • title =例如在我的应用程序导航中使用

由于每个项目可以有任意数量的段,我创建了一个自定义路由,允许我处理这些类型的请求,而不使用默认路由并且只有一个贪婪的路由参数。

项目类型实际上将定义特定项目的内容应以何种方式显示给客户端。我想创建尽可能多的控制器,以便在单个控制器操作中没有太多代码。

那么您将如何在ASP.NET MVC中执行此操作,或者您认为最可行的方法是什么?

编辑:更多细节

我的项目存储在数据库中。由于它们可以有非常不同的类型(不可继承),我想创建尽可能多的控制器。但问题出现了:

  1. 我应该如何在每个请求上创建这些控制器,因为它们与某些动态数据相关?我可以创建自己的Controller工厂或Route处理程序,或者也可能创建一些其他扩展点,但哪一个最好?

  2. 我想使用MVC基本功能来使用像Html.ActionLink(action, controller, linkText)之类的东西,或者使用我自己的扩展名Html.ActionLink(itemType, linkText)来使其更加灵活,因此Action链接应该根据Route创建正确的路由数据(因为这是在后台发生的事情 - 它通过自上而下的路径查看哪一个返回结果URL。)

  3. 我在考虑配置 itemType 路由值(控制器,操作,默认值)之间的关系。默认设置可能很棘手,因为默认值应该从配置字符串反序列化为对象(也可能很复杂)。所以我想甚至可能在 itemType 类类型之间有一个可配置的关系,它实现了一个特定的接口,如下面的例子所示。

  4. 我的路线可以在数据存储中更改(或添加一些新的路线)。但不应添加新类型。配置将提供这些方案,因为它们将链接类型与路由默认值。

  5. 示例

    界面定义:

    public interface IRouteDefaults
    {
        object GetRouteDefaults();
    }
    

    接口实现示例:

    public class DefaultType : IRouteDefaults
    {
        public object GetRouteDefaults()
        {
            return new {
                controller = "Default",
                action = "Show",
                itemComplex = new Person {
                    Name = "John Doe",
                    IsAdmin = true
                }
        }
    }
    

    配置示例:

    <customRoutes>
        <route name="Cars" type="TypeEnum.Car" defaults="MyApp.Routing.Defaults.Car, MyApp.Routing" />
        <route name="Fruits" type="TypeEnum.Fruit" defaults="MyApp.Routing.Defaults.Fruit, MyApp.Routing" />
        <route name="Shoes" type="TypeEnum.Shoe" defaults="MyApp.Routing.Defaults.Shoe, MyApp.Routing" />
        ...
        <route name="Others" type="TypeEnum.Other" defaults="MyApp.Routing.Defaults.DefaultType, MyApp.Routing" />
    </customRoutes>
    

    为了解决性能问题,我可以缓存项目并处理内存数据,避免在每次请求时访问数据库。这些项目往往不会经常变化。我可以将它们缓存60分钟,而不会降低应用程序体验。

2 个答案:

答案 0 :(得分:3)

如果您定义复杂的路由字典,或者只有一个通用路由条目并自己处理所有情况,则不存在重大性能问题。代码是代码

即使您的数据类型不可继承,您也很可能拥有常见的显示模式。 e.g。

  • 标题和摘要文本列表
  • 项目显示,标题,图像,描述

如果您可以将网站细分为有限数量的显示模式,那么您只需要制作那些有限的控制器和视图

您提供的服务层由路由参数选择,而不是使用数据传输对象(DTO)模式获取案例数据并将其移动到视图的标准数据结构中

答案 1 :(得分:2)

你提到的一般概念并不罕见,有几点需要考虑:

  1. 当我听说URL路由依赖于来自数据库的数据时,我首先想到的是性能。缓解潜在性能问题的一种方法是使用内置的Route类并具有非常通用的模式,例如"somethingStatic/{*everythingElse}"。这样,如果URL不以“somethingStatic”开头,它将立即无法匹配,路由将继续到下一个路由。然后你将获得所有有趣的数据作为catch-all“everythingElse”参数。

  2. 然后,您可以将此路由与从MvcRouteHandler派生的自定义路由处理程序关联,并覆盖GetHttpHandler以转到数据库,了解“everythingElse”值,并且可能是动态的确定应该使用哪个控制器和操作来处理此请求。您可以访问requestContext.RouteData.Values

  3. 来获取/设置路由值
  4. 是否使用一个控制器和一个动作,或者每个动作中的一个或多个是多个,这本身就是一个讨论。问题归结为你有多少种不同类型的数据?它们大多相似(它们都是书籍,但有些是精装书,有些是精装书)?完全不同(有些是汽车,有些是书籍,有些是房屋)?如果这是一个计算机编程类,你必须从OOP的角度决定它们是否都有一个基类和它们自己的派生类型,或者它们是否可以很容易地由一种常见的类型。如果它们都是不同的类型,那么我会推荐不同的控制器 - 特别是如果每​​个控制器需要一组不同的动作。例如,对于房屋,您可能希望查看检查报告。但对于一本书,您可能希望预览前五页并阅读书评。这些项目没有任何共同点:一个人的行动永远不会用于另一个。

  5. #3中描述的问题也可以反过来发生:如果你有1000种不同的对象类型怎么办?你想要1000个不同的控制器吗?在没有任何更多信息的情况下,我会说在这种情况下,1,000个控制器有点太多了。

  6. 希望这些想法可以帮助您找到正确的解决方案。如果您可以提供有关您拥有的某些特定方案的更多信息(例如这些方案的类型以及可以对其应用的操作),那么答案也可以进行改进。