1

我正在构建一个需要将以下 URL 映射到其各自控制器的网站;

  • van-insurance/quote1 映射到 EditVehicleController
  • van-insurance/quote2 映射到 EditProposerController
  • van-insurance/quote3 映射到 EditAdditionalDriversController
  • van-insurance/quote4 映射到 EditPolicyController

在每种情况下,所需的操作都是显示,没有参数。

我可以添加一个模式为“van-insurance/{quotePage}”的路由,它将匹配四个 URL,但我不知道如何获取“quotePage”的值,然后使用它来告诉 ASP .NET MVC 哪个控制器使用。

有谁知道如何做到这一点?

4

3 回答 3

1

尝试这个:

routes.MapRoute(
    name: "van-insurance/quote1",
    url: "van-insurance/quote1",
    defaults: new { controller = "EditVehicleController", action = "Show", id = UrlParameter.Optional }
);

routes.MapRoute(
    name: "van-insurance/quote2",
    url: "van-insurance/quote2",
    defaults: new { controller = "EditProposerController", action = "Show", id = UrlParameter.Optional }
);

routes.MapRoute(
    name: "van-insurance/quote3",
    url: "van-insurance/quote3",
    defaults: new { controller = "EditAdditionalDriversController", action = "Show", id = UrlParameter.Optional }
);

routes.MapRoute(
    name: "van-insurance/quote4",
    url: "van-insurance/quote4",
    defaults: new { controller = "EditPolicyController", action = "Show", id = UrlParameter.Optional }
);

无论如何,我建议您使用另一种方法,因为这种方法不容易改变。

var vanInsuranceRoutes = new List<Tuple<string, string>>
                    {
                        new Tuple<string, string>("quote1", "EditVehicleController"),
                        new Tuple<string, string>("quote2", "EditProposerController"),
                        new Tuple<string, string>("quote3", "EditAdditionalDriversController"),
                        new Tuple<string, string>("quote4", "EditPolicyController"),
                    };

foreach (var route in vanInsuranceRoutes)
{
    routes.MapRoute(
        name: string.Format("van-insurance/{0}", route.Item1),
        url: string.Format("van-insurance/{0}", route.Item1),
        defaults: new { controller = route.Item2, action = "Show", id = UrlParameter.Optional });
}

你可以提高代码的质量,但你明白了。

于 2013-07-06T07:36:19.330 回答
1

您的路线中没有任何内容可以指示如何映射到控制器,因此,您必须在某处有代码来执行此映射。

如果您只对调用代码进行映射的单个路由感兴趣,那么您可能会考虑这样的事情:

https://stackoverflow.com/a/16511451/61164

本质上,您可以基于单个路由构建控制器,但在自定义路由控制器中,您可以将路由值映射到正确的控制器。

于 2013-07-06T08:48:03.370 回答
1

感谢 Mystere Man 和 Nikolay Kostov,我得到了这个工作,感谢你们的帮助。我创建了一个自定义路由,它有一个字典来映射页面名称和控制器,就像这样;

private static readonly IDictionary<string, Type> Map = CreateControllerPageMap();

private static IDictionary<string, Type> CreateControllerPageMap()
{
    var map = new Dictionary<string, Type>();
    map.Add("quote1", typeof(EditVehicleController));
    map.Add("quote2", typeof(EditProposerController));
    map.Add("quote3", typeof(EditAdditionalDriversController));
    map.Add("quote4", typeof(EditPolicyController));
    return map;
}

我对 GetRouteData 的覆盖看起来像这样;

public override RouteData GetRouteData(HttpContextBase httpContext)
{
    var routeData = base.GetRouteData(httpContext);
    SetRouteData(routeData);
    return routeData;
}

private static void SetRouteData(RouteData routeData)
{
    var quotePage = routeData.GetRequiredString("quotePage");
    var controller = Map[quotePage].Name.Replace("Controller", string.Empty);
    routeData.Values["controller"] = controller;
    routeData.Values["action"] = "Edit";
}

最后一步就是像这样注册路线;

routes.Add("QuoteJourney", new QuoteJourneyRoute("compare-van-insurance/{quotePage}", new MvcRouteHandler()));

那工作得很好。但是我随后发现 RedirectToAction 生成的 URL 不正确,因为 ASP .NET MVC 不知道如何将控制器名称和操作名称映射回 URL。这已通过覆盖 GetVirtualPath 解决;

public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
    var virtualPathData = base.GetVirtualPath(requestContext, values);
    SetVirtualPath(values, virtualPathData);
    return virtualPathData;
}

private static void SetVirtualPath(IDictionary<string, object> values, VirtualPathData virtualPathData)
{
    var controller = values["controller"] + "Controller";
    var quotePage = Map.Keys.Single(k => Map[k] == Map.Values.Single(v => v.Name == controller));
    virtualPathData.VirtualPath = "compare-van-insurance/" + quotePage;
}

排序!

于 2013-07-06T17:18:09.897 回答