1
votes

I'm using MVC.SiteMap, with some success. The only problem arises when I have a 3 steps path (or more). Let me share some of the code to clarify my problem:

After some clean-up, this is my route table:

        routes.MapRouteWithName(
            name: "RealizacaoPesquisa",
            url: "RealizacaoPesquisa/{action}/{idPesquisa}/{nrProntuario}/{id}",
            defaults: new { controller = "RealizacaoPesquisa", action = "Index", idPesquisa = UrlParameter.Optional, nrProntuario = UrlParameter.Optional, id = UrlParameter.Optional }
        );

        routes.MapRouteWithName(
            name: "Geral",
            url: "{controller}/{action}/{id}/{str}",
            defaults: new { controller = "Home", action = "Index" }
        );

        routes.MapRouteWithName(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

And this is my SiteMap XML:

<mvcSiteMapNode title="Realização de Pesquisas" controller="RealizacaoPesquisa" action="Index">
  <mvcSiteMapNode title="Participação de Pesquisa" controller="RealizacaoPesquisa" action="Participacao" preservedRouteParameters="idPesquisa">
    <mvcSiteMapNode title="Paciente em Pesquisa" controller="RealizacaoPesquisa" action="ParticipacaoPaciente" preservedRouteParameters="idPesquisa;nrProntuario"/>
  </mvcSiteMapNode>
</mvcSiteMapNode>

What I expect:

1) When visiting the first page (action = "Index"), it would show Realização de Pesquisas.

2) When visiting the second page (action = "Participacao", idPesquisa = 2), it would show Realização de Pesquisas > Participação de Pesquisas.

3) When visiting the third page (action = "ParticipacaoPaciente", idPesquisa = 2, nrProntuario = "032"), it would show Realização de Pesquisas > Participação de Pesquisas > Paciente em Pesquisa.

Right now, it works except for item 3 (on item 3 it simply won't render anything, taking me to believe that it's not matching any XML node for the siteMap).

EDIT:

Another attempt that rendered the same result, was using the following routes:

        routes.MapRouteWithName(
            name: "RealizacaoPesquisa_Participacao",
            url: "RealizacaoPesquisa/Participacao/{idPesquisa}",
            defaults: new { controller = "RealizacaoPesquisa", action = "Participacao" }
        );

        routes.MapRouteWithName(
            name: "RealizacaoPesquisa_Participacao_Paciente",
            url: "RealizacaoPesquisa/ParticipacaoPaciente/{idPesquisa}/{nrProntuario}",
            defaults: new { controller = "RealizacaoPesquisa", action = "ParticipacaoPaciente" }
        );

        routes.MapRouteWithName(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

Again, when accessing the first step: http://localhost:61404/RealizacaoPesquisa everything was good;

when acessing the second step: http://localhost:61404/RealizacaoPesquisa/Participacao/27 everything was still ok;

but when I got to the third step: http://localhost:61404/RealizacaoPesquisa/ParticipacaoPaciente/27/0002642811 No Breadcrumb trail rendered.

Any help?

1

1 Answers

1
votes

You are correct in your assumption that the node does not match the route in this case.

The route

routes.MapRouteWithName(
    name: "RealizacaoPesquisa",
    url: "RealizacaoPesquisa/{action}/{idPesquisa}/{nrProntuario}/{id}",
    defaults: new { controller = "RealizacaoPesquisa", action = "Index", idPesquisa = UrlParameter.Optional, nrProntuario = UrlParameter.Optional, id = UrlParameter.Optional }
);

has 5 parameters. You are only accounting for 4 of them in your node. When you don't pass an parameter marked as UrlParameter.Optional to a route, your route will still contain the route key with a value of "".

Key     Value

id      ""

So, in order for it to match you need to specify it in PreservedRouteParameters.

<mvcSiteMapNode title="Paciente em Pesquisa" controller="RealizacaoPesquisa" action="ParticipacaoPaciente" preservedRouteParameters="idPesquisa;nrProntuario;id"/>

However, your routing is also invalid. Only 1 optional parameter can be used and it must always be the right-most parameter. If you don't do this, then the routing framework won't understand how to build the URL when you leave out an optional parameter that is not the right-most value.

To get the effect (I think) you are looking for, you will need to break it into at least 2 routes.

routes.MapRouteWithName(
    name: "RealizacaoPesquisa1",
    url: "RealizacaoPesquisa/{action}/{idPesquisa}",
    defaults: new { controller = "RealizacaoPesquisa", action = "Index", idPesquisa = UrlParameter.Optional }
);

routes.MapRouteWithName(
    name: "RealizacaoPesquisa2",
    url: "RealizacaoPesquisa/{action}/{idPesquisa}/{nrProntuario}/{id}",
    defaults: new { controller = "RealizacaoPesquisa", action = "Index", id = UrlParameter.Optional }
);