SaaS CMS has officially launched! Learn more now.

Razor pages for commerce



I am having trouble creating a razor page for commerce content. 

I have this generic product:

    DisplayName = "GenericProduct",
    GUID = "d0330f27-9343-48b6-b15b-393a8405f5cc",
    Description = "")]
public class GenericProduct : ProductContent
{ }

And this razor page: 

public class GenericProductPageModel : RazorPageModel<GenericProduct>
    private readonly ILogger<GenericProductPageModel> _logger;
    private readonly ILayoutViewModelFactory _layoutViewModelFactory;

    public GenericProductPageModel(ILogger<GenericProductPageModel> logger, ILayoutViewModelFactory layoutViewModelFactory)
        _logger = logger;
        _layoutViewModelFactory = layoutViewModelFactory;

    public void OnGet(GenericProduct product)

However, when visiting a product, I get an 404.

If I create a similar page, but with MVC as below:

public class ProductController : ContentController<GenericProduct>

    public async Task<ActionResult> Index(GenericProduct currentContent)
        return Redirect("/");

I am infact able to get a result. 

Is razor pages not supported for commerce?

Edited, Jun 14, 2024 8:29

You don't typically pass a page around in razor pages. Your razor page itself is the object that gets injected into the attached view.

Instead return Page()

and make the _layoutViewModelFactory return its object to the property of the page. Since its a layout object, you'll want to create a BaseRazorPageModel which contains your layout object then have your razor page inherit from there.

It's not clear from your screenshots but your razor page should consist of a view and page model thats bound together. If you're using VIsual Studio you should see the Page Model hanging off the view in the solution explorer.

Jun 15, 2024 8:50
Christian Morup - Jun 15, 2024 17:56
Thank you for your response.

I've tried implementing this with and without passing the page to the razor page, but unfortunately, neither approach works. The documentation and examples for integrating razor pages with Optimizely Commerce are limited.

Regarding your point about needing to return Page(), this isn't necessary for razor pages, as indicated by one of the examples provided (

Additionally, there is a cshtml file associated with my razor page. However, I consider this detail to be irrelevant to the core issue: the razor page(specifically the OnGet method) is not invoked when accessing a product page, resulting in a 404 error. This behavior differs from that observed with MVC. It appears that Optimizely may not support razor pages for commerce applications, only for CMS.
Surjit Bharath - Jun 15, 2024 18:13
Can you inspect CurrentContent in the OnGet method to see if its being populated with the GenericProduct
Surjit Bharath - Jun 15, 2024 18:16
Did you get a razor page working with a CMS page?
Christian Morup - Jun 15, 2024 18:42
I cannot inspect it because it never invokes the OnGet method :)

And yes, razor pages works perfectly for CMS pages.
Christian Morup - Jun 15, 2024 18:47
It seems that RazorPageModels are exclusively registered for CMS content, although I haven't found definitive confirmation of this

Hi Christian

You might need to check the following 2 things 

#1 - Have you configured endpoint routing for razor pages in your Startup? 

 app.UseEndpoints(endpoints =>

#2 -  What do you place your razor pages?  By default, the core runtime look for Razor page file in the /Pages folder.

I hope above helps.

Jun 16, 2024 14:56
Christian Morup - Jun 17, 2024 6:51
Hi Vincent,

Thank you for your feedback. We have already implemented the changes you mentioned:

#1 - We've configured our startup file as follows:
app.UseEndpoints(endpoints =>

#2 - We are using a folder other than /Pages intentionally to align with our vertical slice architecture approach, which is reflected in our setup:
.AddRazorPagesOptions(options => { options.RootDirectory = "/"; })

This configuration works well for our content pages which is also located in the corresponding "Feature" folder.

If you have any other suggestions or a working example that could help us further, we would be happy to see it.
Vincent - Jun 17, 2024 10:17
Can you try to move you product page razor to /Pages folder and give a try? This is what we suggested in our docs

From memory, /Pages is something not easy to change without deeply customise for razor page itself. I doubt your configuration for feature folder has much to do with razor pages.
Christian Morup - Jun 17, 2024 10:47
I just did and it gives the same result. :(

I am afraid that your memory is wrong regarding the Pages-folder. /Pages is easily changed with AddRazorPagesOptions(options => { options.RootDirectory = "/"; }) as shown above - and it works just perfectly with CMS-pages - however not with commerce (for reasons I don't understand).

You can read the docs for the razor page options in .NET 8 here:

Hi Christian

I did a quick test using Optimizely empty commerce template, it seems working fine with default razor pages configuration and convention (see screenshot below). At this stage, I think you might have some advanced configurations in your solution that alter the routing behavior. 

Jun 18, 2024 1:41
Christian Morup - Jun 18, 2024 7:06
Interesting! I will give it a look. Thanks :)
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.