Open bjarnef opened 6 years ago
@soreng do you have a suggestion how to solve cache by member for LeBlender grid editors?
@bjarnef I would suggest not caching the content for this.
Maybe you can use output caching in the page-controller, to get a similar result
@soreng I tried with [OutputCache]
on the LeBlender controller Index method, but didn't seem to work when I rendered DateTime.Now
.
public class CategoryProductListController : LeBlenderController
{
[OutputCache(Duration = 3600, VaryByParam = "None", VaryByCustom = "User", Location = OutputCacheLocation.Server)]
public ActionResult Index(LeBlenderModel model)
{
return View(model);
}
}
However inside the grid editor I have some condition to render different actions from a SurfaceController, which returns another view e.g.
Html.RenderAction("GetProducts", "ProductList", new { ids = productPickerModel.SelectedProducts, pageSize = 12, mode = "carousel" });
When I use [OutputCache]
on this action method DateTime.Now
in this view is cached.
[OutputCache(Duration = 3600, VaryByParam = "None", VaryByCustom = "UserType")]
public ActionResult GetProducts([ModelBinder(typeof(IntArrayModelBinder))] int[] ids, int page = 1, int pageSize = 10, SortBy sortBy = SortBy.None, SortDirection sortDirection = SortDirection.Ascending, string mode = "")
{
int total = 0;
var products = MyRepo.GetProducts(ids, page, pageSize, out total, false, sortBy, sortDirection);
var pager = new PagerModel(pageSize, page - 1, total);
var listModel = new ListModel(products, pager);
ViewData["mode"] = mode;
return View("/Views/Partials/ProductList.cshtml", listModel);
}
@soreng would it be possible to make this LeBlenderPartialCacher
https://github.com/Lecoati/LeBlender/blob/e11905f192a1cb733ec012404998ff74f0b56ca5/Src/Lecoati.LeBlender.Extension/LeBlenderPartialCacher.cs
similar to CachedPartial
in core?
https://github.com/umbraco/Umbraco-CMS/blob/7ee510ed386495120666a78c61497f58ff05de8f/src/Umbraco.Web/HtmlHelperRenderExtensions.cs#L80
I dont see why it could’nt just use the method from core directly - but keep in mind LeBlender is build Against umbraco 7.4.
But back to the question. It requires the value of cacheByMember to be true somehow. My concern on this was that it could add alot stuff to memory if we are not carefull. It could be done via an attribute on the controller maybe?
@soreng it seems this extension class haven't changed much the last couple of years https://github.com/umbraco/Umbraco-CMS/commits/7ee510ed386495120666a78c61497f58ff05de8f/src/Umbraco.Web/HtmlHelperRenderExtensions.cs
When the core CachedPartial allowing caching by member and macros has this feature, would it make sense to allow this for LeBlender grid editors as well?
Furthermore the CachedPartial
has a contextualKeyBuilder parameter, which can be used in e.g. a multi-site solution where same partials are used in each site, in this case it will be cached by domain.
@Html.CachedPartial("~/Views/Partials/MainMenu.cshtml", Model.Content, 1209600, contextualKeyBuilder: (model, viewData) => Request.Url.Host)
I have tried added the OutputCache
on the LeBlender controller and the Index method, but it didn't seem to have any effect, but it does cache the partials when I add OutputCache
on the action methods in my SurfaceController and these are rendered inside the LeBlender grid editor view, e.g.
[OutputCache(Duration = 3600, VaryByParam = "None", VaryByCustom = "Url;User")]
public ActionResult GetProducts([ModelBinder(typeof(IntArrayModelBinder))] int[] ids, int page = 1, int pageSize = 10, SortBy sortBy = SortBy.None, SortDirection sortDirection = SortDirection.Ascending)
{
int total = 0;
var products = ProductService.GetProducts(ids, page, pageSize, out total, false, sortBy, sortDirection);
var pager = new PagerModel(pageSize, page - 1, total);
var listModel = new ListModel(products, pager);
return View("/Views/PartialView/ProductList.cshtml", listModel);
}
Html.RenderAction("GetProducts", "ProductList", new { ids = productIds, pageSize = 10 });
and then I have this.
public class Global : UmbracoApplication
{
public override string GetVaryByCustomString(HttpContext context, string custom)
{
var args = custom.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
var sb = new StringBuilder();
foreach (var arg in args)
{
if (arg.InvariantEquals("Url"))
{
var filtered = HttpUtility.ParseQueryString(context.Request.QueryString.ToString());
var absoluteUri = "url=" + context.Request.Url.AbsoluteUri;
if (filtered["umbDebug"] != null)
{
filtered.Remove("umbDebug");
absoluteUri = "url=" + context.Request.Url.AbsoluteUri.Split('?')[0];
if (filtered.Count > 0)
{
absoluteUri += "?" + filtered;
}
}
sb.Append(absoluteUri);
//return absoluteUri;
}
else if (arg.InvariantEquals("User"))
{
if (context.Request.IsAuthenticated)
{
var user = context.User.Identity.Name;
sb.Append("user=" + user);
//return "user=" + user;
}
}
//else if (arg.InvariantEquals("UserType"))
//{
// if (context.Request.IsAuthenticated)
// {
// var umbracoHelper = new UmbracoHelper(UmbracoContext.Current);
// var member = umbracoHelper.MembershipHelper.GetCurrentMember();
// if (member != null)
// {
// sb.Append("usergroup=" + member.ContentType.Alias);
// //return "usergroup=" + member.ContentType.Alias;
// }
// }
//}
}
if (!string.IsNullOrEmpty(sb.ToString()))
{
return sb.ToString();
}
return base.GetVaryByCustomString(context, custom);
}
}
I tried caching by member type, but it seems to create these SQL queries each time, so not sure how to cache an grid editor or partial by member group or member group?
Hi @bjarnef The reason the LeBlender controller output is not affected by the output cache attribute is that the controller is not really used as a "real" controller. It is just there as a method for mapping from LeBlenderModel to your custom model, if needed.
For the caching to work, it should be implemented as you suggest - as it is in macros.
I'm getting ideas for improvements, but they may need a v2 to make them work.
At the moment the caching of the LeBlender grid editors is by page, but it would be useful to cache by member as when using the
CachedPartial
e.g. when you present specific content inside the editor depending on the member type who is logged in.https://24days.in/umbraco-cms/2017/the-one-with-performance/performance-boosts-for-umbraco/
https://our.umbraco.com/projects/backoffice-extensions/leblender/general-discussion/92538-caching-of-user-specific-content-in-leblender