Razor pages working on .Net Core 3.0?

I am trying to move our Netcore 2.2 web project to 3.0, but I am stuck with Razor it seems.
Whichever view I try to serve from my services, it always resorts to the DTO being passed and gives the default ServiceStack results page.
Can you confirm that .Net 3.0 Razor pages can be served with the RazorFormat plugin?

Things I have tried:

  • Include RazorFormat from source

  • Include Asp.Net Core Razor from source using a ‘custom’ ViewEngine which is just a copy of the existing ViewEngine --> Every call seems to not find my views

    // Internal for unit testing
    internal ViewLocationCacheResult CreateCacheResult(
      HashSet<IChangeToken> expirationTokens,
      string relativePath,
      bool isMainPage)
    {
    var factoryResult = _pageFactory.CreateFactory(relativePath); // <-- this will always return a NOT FOUND viewDescriptor
    var viewDescriptor = factoryResult.ViewDescriptor;
    if (viewDescriptor?.ExpirationTokens != null)
    {
      var viewExpirationTokens = viewDescriptor.ExpirationTokens;
      // Read interface .Count once rather than per iteration
      var viewExpirationTokensCount = viewExpirationTokens.Count;
      for (var i = 0; i < viewExpirationTokensCount; i++)
      {
        expirationTokens.Add(viewExpirationTokens[i]);
      }
    }
    if (factoryResult.Success)
    {
      // Only need to lookup _ViewStarts for the main page.
      var viewStartPages = isMainPage ?
          GetViewStartPages(viewDescriptor.RelativePath, expirationTokens) :
          Array.Empty<ViewLocationCacheItem>();
    
      return new ViewLocationCacheResult(
          new ViewLocationCacheItem(factoryResult.RazorPageFactory, relativePath),
          viewStartPages);
    }
    
    return null;
    }
    

The piece of code above is taken from the namespace Microsoft.AspNetCore.Mvc.Razor. Specifcally public class RazorViewEngine: IRazorViewEngine

I must be doing something wrong, but I am seeking confirmation that Razor DOES work with the SS 5.7.0

These existing projects (from Upgrading to .NET Core 3.0 release notes) all use RazorFormat and are now running on .NET Core 3.0:

OK, that is confirmation :slight_smile: The project is changed accoring to the release notes, so that should not be an issue. The weird thing is that the code worked with 2.2 and not with 3.0. The pageFactory seems to be a culprit, but I cannot put my finger on the issue… It just cannot find the views. Any hints or ideas?

There are APIs in RazorFormat like GetPageFromPathInfo(string pathInfo) and HasView(string viewName, IRequest httpReq = null) you can use in your Service to try resolve pages, e.g:

GetPlugin<RazorFormat>().HasView(nameof(MyRequest));

They call into the same function with the same issue. I will try to create a small web project and see if the behaviour is the same.

After some days of crunching and debugging, I found the culprit(s). Here they are in random order:

  • If any of the following lines are present in the .csproj file, the views may or may not work (no consistent behaviour)

    <RazorCompileOnBuild>false</RazorCompileOnBuild>
    <RazorCompileOnPublish>false</RazorCompileOnPublish>
    <MvcRazorCompileOnBuild>false</MvcRazorCompileOnBuild>
    <MvcRazorCompileOnPublish>false</MvcRazorCompileOnPublish>

  • If a view is set on the request with a name containing a ‘/’, the view will not work. I used this because I wanted to use views in specific folders.

Request.Items["View"] = "Pages/Advertisement/AdvertisementDetailsMessage";

This is a change from the 2.X version (probably Net Core itself) but may be worth putting in the Release Notes.

Maybe it’s just MvcRazorCompileOnPublish?

<MvcRazorCompileOnPublish>false</MvcRazorCompileOnPublish>

This is also needed to avoid pre-compiled views when using page-based routing:
https://docs.servicestack.net/netcore-razor#limitation

Basically whenever the views can’t be statically resolved.

That was my first hunch. If any of the directives are present, resolving the views will fail at some point. I have not completely figured out why though…