Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Umbraco.Docs.Samples.Web/Custom-Routes/Product.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Collections.Generic;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.PublishedContent;

namespace Umbraco.Docs.Samples.Web.Custom_Routes
{
public class Product : ContentModel
{
public Product(IPublishedContent content) : base(content)
{
}

public string Sku { get; set; }
public IEnumerable<string> AvailableStores { get; set; }
}
}
98 changes: 98 additions & 0 deletions Umbraco.Docs.Samples.Web/Custom-Routes/ShopController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Core.Web;
using Umbraco.Cms.Web.Common.Controllers;
using Umbraco.Extensions;

namespace Umbraco.Docs.Samples.Web.Custom_Routes
{
public class ShopController : UmbracoPageController, IVirtualPageController
{
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
private readonly IPublishedValueFallback _publishedValueFallback;

public ShopController(
ILogger<UmbracoPageController> logger,
ICompositeViewEngine compositeViewEngine,
IUmbracoContextAccessor umbracoContextAccessor,
IPublishedValueFallback publishedValueFallback)
: base(logger, compositeViewEngine)
{
_umbracoContextAccessor = umbracoContextAccessor;
_publishedValueFallback = publishedValueFallback;
}

public IPublishedContent FindContent(ActionExecutingContext actionExecutingContext)
{
var umbracoContext = _umbracoContextAccessor.GetRequiredUmbracoContext();

if (umbracoContext == null)
{
return null;
}

var productRoot = umbracoContext.Content.GetById(2074);
if (actionExecutingContext.ActionDescriptor is not ControllerActionDescriptor controllerActionDescriptor)
{
return productRoot;
}

// Check which action is executing
switch (controllerActionDescriptor.ActionName)
{
case nameof(Index):
return productRoot;

case nameof(Product):
// Get the SKU/Id from the route values
if (actionExecutingContext.ActionArguments.TryGetValue("id", out var sku))
{
return productRoot
.Children
.FirstOrDefault(c => c.Value<string>(_publishedValueFallback, "sku") == sku.ToString());
}
else
{
return productRoot;
}
}

return productRoot;
}

[HttpGet]
public IActionResult Index()
{
// CurrentPage (IPublishedContent) will be the content returned
// from the FindContent method.

// return the view with the IPublishedContent
return View(CurrentPage);
}

[HttpGet]
public IActionResult Product(string id)
{
// CurrentPage (IPublishedContent) will be the content returned
// from the FindContent method.

// One example of using a custom route would be to include additional
// model information based on external services. For example, if
// we wanted to return the stores the product is available in from
// a custom data store.
var dbProduct = DbContext.Products.GetBySku(id);
var shopModel = new Product(CurrentPage)
{
Sku = id,
AvailableStores = dbProduct.AvailableStores
};

return View(shopModel);
}
}
}
5 changes: 5 additions & 0 deletions Umbraco.Docs.Samples.Web/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
})
.WithEndpoints(u =>
{
u.EndpointRouteBuilder.MapControllerRoute(
"Shop Controller",
"/shop/{action}/{id?}",
new { Controller = "Shop", Action = "Index" });

u.UseInstallerEndpoints();
u.UseBackOfficeEndpoints();
u.UseWebsiteEndpoints();
Expand Down