matchesPathInfo not finding pathinfo in tempates model view controller

I’ve been trying to get the active menu working in a partial template but it appears that the PathInfo is not being found correctly.

I was wondering if I might be doing something wrong.

The setup is a netcore console app, using kestrel and the apphost has the TemplatePagesFeature plugin registered.

I have a service with the following

public class ViewService : Service
{
  public object Any(ViewIndex request) => new  PageResult(Request.GetPage("/index"));

  public object Any(ViewLogs request) => new  PageResult(Request.GetPage("/logs")); 
...
}

[Route("/index")]
// [Route("/")] throws route is invalid exception
public class ViewIndex { }

[Route("/logs")]
public class ViewLogs { }

I have the following four files

\wwwroot\_layout.html
\wwwroot\menu.html
\wwwroot\index.html
\wwwroot\logs.html

the menu partial is bascially identical to the example but with the links collection altered. the layout is again much like the examples with the
the partial defined.
``{{ ‘menu’ | partial }}```

and the {{ body }} which is rendering the pages ok.

The index and log pages are bascially empty except for a title.

Firstly, when launching the project, the index.html page is rendered fine and route ‘’ is matched with the ‘active’ class being rendered.
However, it is not hitting the ViewService.Any(ViewIndex request) method.

How can I get default the root path to use the service method?

If I type the /index url in, the method is hit, but the route is not matched.

If I navigate to the /logs url, again the service method is hit, but the route is not matched.

I have more pages and the behaviour is the same, when calling the service methods, the matchesPathInfo in the menu partial is unable to get the PathInfo from the request which is why regardless of the path being checked, it is not able to match.

Any suggestions as to what I can try to figure where the problem lies?

You need to use a [FallbackRoute] to be able to handle the default request in a service, see the parcel template for an example:

I’m not sure what the issue with your menu partial is although note with the support for page based routing the recommendation is to use _{name}-partial.html naming convention for partials e.g. _menu-partial.html which still lets you include partials with:

{{ 'menu' | partial }}

The partial template also has an example for this:

Can you provide a minimal repro I can look at for the rest of the issues?

I’ve added a fork from the basic template that shows the issue.

When run, you will find the home and services links are highlighted, and the contact and about are not. Not sure if I did something incorrect with the Fallback route as it wasn’t being hit either.

ok thanks, the view handler was being executed before the fallback handler which is why the default page took preference, I’ve since changed behavior in this commit so that a targeted [FallbackRoute] with either a Matches rule or a Priority < 0 will be executed before the view handler, so your Service should now be called.

The second issue of PathInfo not being populated is because the Request Args are only populated by default when the page is called directly. To also have the Request Args populated in View Pages that render the result of a Service you can either call the IRequest.GetPageResult() extension method or the new PageResult.BindRequest() method, e.g:

public object Any(ViewIndex request) => Request.GetPageResult("/index");

//equivalent to:
public object Any(ViewIndex request) => new PageResult(Request.GetPage("/index")).BindRequest(Request);

These changes is available in the latest v5.4.1 that’s now available on MyGet, if you previously had v5.4.1 installed you’ll need to clear your NuGet packages cache.

1 Like

thanks @mythz. Did the trick.

One quick follow up question. I created a template filter to match sub paths aswell

/blah
/blah/subblah

both match my menu /blah for highlighting

but was wondering if something already existed that I overlooked for this?

Nope but I just added a new startsWithPathInfo() filter you can change your _menu-partial.html to use instead which will also match parent links when viewing sub pages in this commit.

So the /services menu item is marked active in either the /services, /services/acme or /services/acme/widget pages:

{{ { '/':         'Home',
     '/about':    'About',
     '/services': 'Services',
     '/services/acme': 'ACME Services',
     '/services/acme/widget': 'ACME Widget Service',
     '/contact':  'Contact',
   } | toList | assignTo: links }}

<div class="collapse navbar-collapse" id="navbarResponsive">
    <ul class="navbar-nav ml-auto">
        {{#each links}}
        <li {{ {active: startsWithPathInfo(Key)} | htmlClass }}>
            <a class="nav-link" href="{{Key}}">{{Value}}</a>
        </li>
        {{/each}}
    </ul>
</div>

Feel free to PR any other filters you think may be useful to have included by default.

This change is available from the latest v5.4.1 that’s now on MyGet.

1 Like