代码之家  ›  专栏  ›  技术社区  ›  Robert Koritnik

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

  •  8
  • Robert Koritnik  · 技术社区  · 15 年前

    你将如何解决这个问题:

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

    • url=将与请求一起使用的任意数量的第一个路由段
    • some item type=显示将与此类型相关(阅读)
    • title=例如在应用程序周围的导航中使用
    • 等。

    由于每个项目可以有任意数量的段,所以我创建了一个自定义路由,它允许我在不使用默认路由和具有单个贪婪路由参数的情况下处理此类请求。

    项目类型将实际定义特定项目的内容应以何种方式显示给客户机。我在考虑创建和创建控制器一样多的控制器,以避免在单个控制器操作中有太多的代码。

    那么,您将如何在ASP.NET MVC中实现这一点,或者您建议什么是实现这一点的最可行的方法?

    编辑:更多详细信息

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

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

    2. 我想使用MVC的基本功能 Html.ActionLink(action, controller, linkText) 或者让我自己的扩展 Html.ActionLink(itemType, linkText) 为了使其更加灵活,所以动作链接应该基于路由数据创建正确的路由(因为这是后台发生的事情——它自上而下地遍历路由,查看哪个路由返回结果的URL)。

    3. 我正考虑在 项目类型 路由值 (控制器、操作、默认值)。默认值设置可能比较复杂,因为默认值应该从配置字符串反序列化为对象(也可能很复杂)。所以我想也许在 项目类型 类类型 它实现了一个特定的接口,如下面的示例中所写的。

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

    例子 :

    接口定义:

    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 回复  |  直到 14 年前
        1
  •  3
  •   TFD    15 年前

    如果您定义了一个复杂的路由字典,或者只有一个通用的路由条目,并且自己处理所有情况,那么就没有显著的性能问题。代码就是代码

    即使您的数据类型是不可继承的,也很可能有公共的显示模式。例如

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

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

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

        2
  •  2
  •   Eilon    15 年前

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

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

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

    3. 是否使用一个控制器和一个动作,或者一个或多个动作中的一个或多个,这是一个对自身的讨论。问题归结为您有多少种不同类型的数据?它们大多相似吗(都是书,但有些是精装书,有些是软封面)?完全不同(有些是汽车,有些是书,有些是房子)?如果这是一个计算机编程类,并且您必须从OOP的角度来决定它们是否都有一个基类和它们自己的派生类型,或者它们是否可以很容易地用一个公共类型表示,那么这个问题的答案应该与您的答案相同。如果它们都是不同的类型,那么我会推荐不同的控制器——特别是如果每个控制器都需要一组不同的操作。例如,对于房屋,您可能希望看到检查报告。但对于一本书,你可能想预览前五页并阅读书评。这些项目没有任何共同点:一个项目的操作永远不会用于另一个项目。

    4. 但是3中描述的问题也可能以相反的方式出现:如果有1000种不同的对象类型呢?你想要1000个不同的控制器吗?在没有更多信息的情况下,对于这个场景,1000控制器有点太多了。

    希望这些想法能帮助你找到正确的解决方案。如果您可以提供有关您所拥有的某些特定场景的更多信息(例如,这些场景是什么类型的对象,以及可以对其应用哪些操作),那么也可以对答案进行优化。