如何成功编写 MVC 路由定义

本文关键字:MVC 路由 定义 何成功 成功 | 更新日期: 2023-09-27 18:35:17

有人可以帮我找到问题所在,并且仍然向我解释控制器如何知道它应该使用哪个路由定义(因为在很多情况下,URI 可以适合不止一个路由定义)?

这是我的问题...

控制器方法:

[HttpGet]
public ActionResult PreencherFormulario(int idPacientePesquisa, int idFormularioPesquisa) 
路由

(所有路由在 Global.asax 上定义):

protected void Application_Start()
{
    RouteTable.Routes.MapRoute(
        "Busca",
        "{controller}/{action}/{SearchString}/{SearchSubString}/{id}"
    );
    RouteTable.Routes.MapRoute(
        "Participacao",
        "{controller}/{action}/{id}"
    );
    RouteTable.Routes.MapRoute(
        "ParticipacaoPesquisa",
        "{controller}/{action}/{idPesquisa}/{nrProntuario}",
        null,
        new { idPesquisa = @"'d+" }
     );
    //!!! This should be the one used...
    RouteTable.Routes.MapRoute(
        name: "PreencherForm",
        url: "{controller}/{action}/{idPacientePesquisa}/{idFormularioPesquisa}",
        defaults: new { idPacientePesquisa = 1, idFormularioPesquisa = 1 },
        constraints: new { idPacientePesquisa = @"'d+", idFormularioPesquisa = @"'d+" }
     );
    RouteTable.Routes.MapRoute(
        "AdicionarRegraCID",
        "{controller}/{action}/{a}/{b}/{c}",
        new { controller = "Pesquisas", action = "AdicionarRegraCID", MetodoResultado = "", MetodoCancelar = "" }
    );

网址:

http://localhost:61404/RealizacaoPesquisa/PreencherFormulario/1/1

错误:

The parameters dictionary contains a null entry for parameter 'idPacientePesquisa' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult PreencherFormulario(Int32, Int32)' in 'Prometheus.Controllers.RealizacaoPesquisaController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Nome do parâmetro: parameters

如何成功编写 MVC 路由定义

您的问题在于以下路由,该路由默认为 null,并且该路由位于您怀疑的路由之前,并且路由 url 的格式与下一个路由的格式相同。此路由被考虑,并且在路由时失败,因为您的操作参数是不可为 null 的 int。

  RouteTable.Routes.MapRoute(
        "ParticipacaoPesquisa",
        "{controller}/{action}/{idPesquisa}/{nrProntuario}",
        null, /*<--- This is the culprit*/
        new { idPesquisa = @"'d+" }
  );
请记住,路线

的顺序很重要,您也应该将默认路线保留在底部。将上面的路线移动到有问题的路线下方。您需要重新安排路线。事情是这样的:

您点击网址:http://localhost:61404/RealizacaoPesquisa/PreencherFormulario/1/1

它查看路由表并找到第一个匹配项,即

"{controller}/{action}/{idPesquisa}/{nrProntuario}",

因此,然后它会尝试使用参数调用您的操作 idPesquisa 这是此路由中映射的内容。

但是您的操作需要其他内容作为参数名称,并且它们也是不可空的,因此如果失败。

首先,您要编写从更具体到更通用的路由。它使用它匹配的第一个。

所以你的问题是你的路由与这条路线匹配,你正在将idPacientPesqusa设置为空。

 RouteTable.Routes.MapRoute(
        "ParticipacaoPesquisa",
        "{controller}/{action}/{idPesquisa}/{nrProntuario}",
        null, <-- here!!
        new { idPesquisa = @"'d+" }
     );

您似乎正在尝试为每个控制器/操作设置路由,以便您可以执行以下操作

 RouteTable.Routes.MapRoute(
        name: "PreencherForm",
        url:"RealizacaoPesquisa/PreencherFormulario/{idPacientePesquisa}/{idFormularioPesquisa}",
        defaults: new { controller = "RealizacaoPesquisa", action = "PreencherFormulario", idPacientePesquisa = 1, idFormularioPesquisa = 1 },
        constraints: new { idPacientePesquisa = @"'d+", idFormularioPesquisa = @"'d+" }
     );