Cannot render a macro when there is no current PublishedContentRequest (Custom Controller/Model)
Hi,
I'm sure this is a familiar issue - I've found threads with the same problem, but unfortunately not fix it for me.
I'm also aware I can use [EnsurePublishedContentRequest(Id)], but unfortunately that solution also isn't available to me here.
As a quick overview, I'm using Umbraco as the 'Core' of my website, where some pages are dynamically generated via an API.
On an API generated page, I need to ability to add macros which is causing the above error. Any help would be very appreciated, it may well even be something very obvious that I've missed!
Controller:
public class ApiPageController : RenderMvcController
{
public ActionResult Item(RenderModel model, string apiId)
{
// connect to the API and get the item page
var api = new ApiConnection();
var apiResult = api.getPage(apiId);
UmbracoHelper UH = new UmbracoHelper(UmbracoContext.Current);
var UmbracoApiPage = UH.TypedContentAtRoot()
.DescendantsOrSelf("ApiContent")
.Where(pc => pc.GetPropertyValue("apiId") != null)
.FirstOrDefault();
var vm = new ApiViewModel(UmbracoApiPage, CultureInfo.CurrentUICulture);
// RouteData.DataTokens["umbraco"] = vm;
// RouteData.DataTokens["umbraco-doc-request"] = UmbracoContext.Current.PublishedContentRequest;
// RouteData.DataTokens["umbraco-context"] = UmbracoContext.Current;
// assign the page to the View Model
vm.apiPage = apiResult;
return View(vm);
}
}
Model:
public class ApiViewModel : RenderModel
{
// Not used, left in as a fallback
public ApiViewModel() : this(new UmbracoHelper(UmbracoContext.Current)) { }
// Not used, left in as a fallback
public ApiViewModel(UmbracoHelper Umbraco)
: this(Umbraco.TypedContentAtRoot().FirstOrDefault(), CultureInfo.CurrentUICulture)
{
}
public ApiViewModel(IPublishedContent content, CultureInfo culture)
: base(content, culture)
{
// Dummy constructor
}
public ApiPageResult ApiPage { get; set; }
}
If believe that's the code you need to see, but let me know if you need snippets of the View :)
UmbracoHelper UH = new UmbracoHelper(UmbracoContext.Current);
var UmbracoApiPage = UH.TypedContentAtRoot().DescendantsOrSelf("ApiContent")
.Where(pc => pc.GetPropertyValue("apiId") != null).FirstOrDefault();
You should be able to just do:
var UmbracoApiPage = Umbraco.TypedContentAtRoot().DescendantsOrSelf("ApiContent")
.Where(pc => pc.GetPropertyValue("apiId") != null).FirstOrDefault();
Regarding your problem, I think you may just need to replace your 3 constructors in your ViewModel with 1:
public ApiViewModel() : base(UmbracoContext.Current.PublishedContentRequest.PublishedContent) { }
Also are you following the route naming convention?
A document type with alias "ApiPage"
A template with alias "Item"
And I assume your view ("Item.cshtml") probably starts with:
@inherits UmbracoViewPage<ApiViewModel>
If you're following the standard routes, instead of
return View(vm)
You should be able to do:
return CurrentTemplate(vm);
Also, I'm not sure your ActionResult constructor is ok, but that's just because I've never tried, maybe your way is fine! A thing I know should work would be:
public ActionResult Item(ApiViewModel model)
{
var apiId = Request["apiId"];
....null check etc. //then you can do:
model.ApiPage = new ApiConnection().getPage(apiId)
Regarding the creating a new UmbracoHelper, the only reason I'd opted for this method is because doing Umbraco.TypedContentAtRoot() etc... resulted in the following error:
DataTokens must contain an 'umbraco-doc-request' key with a PublishedContentRequest object
Unfortunately, I'm still given the same error with the changes above implemented.
I implemented the new ViewModel constructor, but I'm afraid UmbracoContext.Current.PublishedContentRequest is null :(
In regards to your other questions:
There is no document type with an alias of "ApiPage" - I didn't think
it was required since these pages or dynamically generated
I do have a template called "Item"
The view page does have @inherits UmbracoViewPage<ApiViewModel> at the top
The ActionResult constructor is working, but I have a custom route setup in Global.asax :)
For anyone else that has this issue, I've found a fix.
Instead of inheriting from RenderModel I had to create a custom model which initiated the PublishedContentRequest (based off the EnsurePublishedContentRequest attribute).
Making custom models inherit from this appears to have fixed it.
public class PublishedContentRenderModel : IRenderModel
{
public PublishedContentRenderModel(IPublishedContent content, CultureInfo culture)
{
if(content == null)
{
content = new UmbracoHelper(UmbracoContext.Current).TypedContentAtRoot().FirstOrDefault();
Content = content;
Culture = culture;
return;
}
var baseUrl = HttpContext.Current.Request.Url.AbsoluteUri.Replace(HttpContext.Current.Request.Path, "/");
var umbUrl = baseUrl + content.Url.TrimStart('/');
var pcr = new PublishedContentRequest(
new Uri(umbUrl),
UmbracoContext.Current.RoutingContext,
UmbracoConfig.For.UmbracoSettings().WebRouting,
s => Roles.Provider.GetRolesForUser(s)
);
UmbracoContext.Current.PublishedContentRequest = pcr;
UmbracoContext.Current.PublishedContentRequest.PublishedContent = content;
pcr.Prepare();
Content = content;
Culture = culture;
}
public PublishedContentRenderModel()
: this(default(IPublishedContent), CultureInfo.CurrentUICulture)
{
}
public IPublishedContent Content { get; set; }
public CultureInfo Culture { get; set; }
}
Cannot render a macro when there is no current PublishedContentRequest (Custom Controller/Model)
Hi,
I'm sure this is a familiar issue - I've found threads with the same problem, but unfortunately not fix it for me.
I'm also aware I can use [EnsurePublishedContentRequest(Id)], but unfortunately that solution also isn't available to me here.
As a quick overview, I'm using Umbraco as the 'Core' of my website, where some pages are dynamically generated via an API.
On an API generated page, I need to ability to add macros which is causing the above error. Any help would be very appreciated, it may well even be something very obvious that I've missed!
Controller:
Model:
If believe that's the code you need to see, but let me know if you need snippets of the View :)
Thanks,
Daniel
A small thing I see is:
You should be able to just do:
Regarding your problem, I think you may just need to replace your 3 constructors in your ViewModel with 1:
Also are you following the route naming convention?
And I assume your view ("Item.cshtml") probably starts with:
If you're following the standard routes, instead of
You should be able to do:
Also, I'm not sure your ActionResult constructor is ok, but that's just because I've never tried, maybe your way is fine! A thing I know should work would be:
Hi Daniel,
Regarding the creating a new UmbracoHelper, the only reason I'd opted for this method is because doing
Umbraco.TypedContentAtRoot()
etc... resulted in the following error:Unfortunately, I'm still given the same error with the changes above implemented.
I implemented the new ViewModel constructor, but I'm afraid
UmbracoContext.Current.PublishedContentRequest
is null :(In regards to your other questions:
@inherits UmbracoViewPage<ApiViewModel>
at the topThe ActionResult constructor is working, but I have a custom route setup in Global.asax :)
Thanks,
Daniel
For anyone else that has this issue, I've found a fix. Instead of inheriting from
RenderModel
I had to create a custom model which initiated the PublishedContentRequest (based off the EnsurePublishedContentRequest attribute).Making custom models inherit from this appears to have fixed it.
is working on a reply...