Umbraco.TypedContent throws object null reference exception when passed an unpublished nodeId
I am working on an umbraco v7.2.8 site. When I have Umbraco.TypedContent(1024); when node with id 1024 is unpublished, Umbraco throws a NullReferenceException. I thought it was just supposed to return null if something that was picked is unpublished. I swear code like this used to work.
var myNode = Umbraco.TypedContent(1024);
if(myNode == null)
{
// deal with it
}
// do stuff with myNode
perhaps you could show the stacktrace for the NullReferenceException?
Looking at the current Umbraco source code, it should indeed return null if it's not found in the cache; so there may be something else going on; and if this is in Razor then it's highly likely that your error is in an entirely different spot in the template.
Oh ya. Sorry about that. Here is the full exception:
Block Exception:System.NullReferenceException: Object reference not set to an instance of an object.
at ASP._Page_Views_Partials_RelatedProductsBlock_cshtml.Execute() in c:\Websites\mywebsite\mywebsite_git\src\mywebsite\Views\Partials\RelatedProductsBlock.cshtml:line 15
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy()
at System.Web.Mvc.WebViewPage.ExecutePageHierarchy()
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)
at Umbraco.Core.Profiling.ProfilingView.Render(ViewContext viewContext, TextWriter writer)
at System.Web.Mvc.Html.PartialExtensions.Partial(HtmlHelper htmlHelper, String partialViewName, Object model, ViewDataDictionary viewData)
at WebBlocks.Views.RenderingEngines.PartialViewRenderingEngine.Render(HtmlHelper html)
This is the partial view. We are using the v7 Mentor Web Blocks package. That's why you see references to CurrentBlock. This is on of the block partial view templates.
@inherits WebBlocks.ViewTemplates.WebBlocksTemplatePage
@{
var title = CurrentBlock.HasValue("title") ? CurrentBlock.title : CurrentBlock.Name;
if(CurrentBlock.HasValue("relatedProducts"))
{
var relatedProductIds = CurrentBlock.relatedProducts.Split(',');
<div class="content_box resources">
<div class="content_box_inner_wrapper">
<h2>@title</h2>
<ul>
@foreach (string relatedProductId in relatedProductIds)
{
var relatedProduct = Umbraco.TypedContent(relatedProductId);
<li><a href="@relatedProduct.Url">@relatedProduct.Name</a></li>
}
</ul>
</div>
</div>
}
}
I can add a breakpoint and step through. relatedProductIds will have multiple nodeIds. Everything is fine until I hit Umbraco.TypedContent(relatedProductId) with an id to a node that is unpublished. Then everything explodes. If I publish the unpublished node, the error goes away. The error will come back if I unpublish the node again. I've tested it with multiple nodes. It isn't just one corrupted node.
I get the same exception in the backoffice block preview and on the frontend of the website. I'm pretty confident that it isn't an issue with Web Blocks. It might be interesting to note that I imported all of the content in this site from a v6 version of the site via customized version of the Conveyor package. Conveyor leverages the ContentService and MediaService though. It isn't doing anything strange as far as the content creation goes. Everything else in the site seems to work as well.
I was able to work around the problem. It looks like the overloads for TypedContent that take an IEnumerable<string> or an IEnumerable<int> don't have any problems. I just refactored the code a bit, so it works like this. I think this is a little bit prettier than what I had anyways.
@inherits WebBlocks.ViewTemplates.WebBlocksTemplatePage
@{
var title = CurrentBlock.HasValue("title") ? CurrentBlock.title : CurrentBlock.Name;
if(CurrentBlock.HasValue("relatedProducts"))
{
var relatedProductIdString = CurrentBlock.relatedProducts as string ?? "";
var relatedProductIds = relatedProductIdString.Split(',');
var relatedProducts = Umbraco.TypedContent(relatedProductIds);
<div class="content_box resources">
<div class="content_box_inner_wrapper">
<h2>@title</h2>
<ul>
@foreach (var relatedProduct in relatedProducts.Where(p => p != null))
{
<li><a href="@relatedProduct.Url">@relatedProduct.Name</a></li>
}
</ul>
</div>
</div>
}
}
I'd still like to understand what was happening with the TypedContent method that takes a single int or a string.
The TypedContent with a single integer does return null when the content is not published. However your code does:
@foreach (string relatedProductId in relatedProductIds)
{
var relatedProduct = Umbraco.TypedContent(relatedProductId);
<li><a href="@relatedProduct.Url">@relatedProduct.Name</a></li>
}
And there, you are not testing whether relatedProduct is null. Hence the nullref exception. Should be:
@foreach (string relatedProductId in relatedProductIds)
{
var relatedProduct = Umbraco.TypedContent(relatedProductId);
if (relatedProduct == null) continue;
<li><a href="@relatedProduct.Url">@relatedProduct.Name</a></li>
}
Alternatively, your workaround would work, too -- and I'm pretty sure you don't need the "p != null" test because relatedProducts would not contain nulls.
Umbraco.TypedContent throws object null reference exception when passed an unpublished nodeId
I am working on an umbraco v7.2.8 site. When I have
Umbraco.TypedContent(1024);
when node with id1024
is unpublished, Umbraco throws a NullReferenceException. I thought it was just supposed to returnnull
if something that was picked is unpublished. I swear code like this used to work.Can anyone set me straight?
It looks like the
Umbraco.TypedContent
method that accepts an array of integers still works as expected.perhaps you could show the stacktrace for the NullReferenceException?
Looking at the current Umbraco source code, it should indeed return null if it's not found in the cache; so there may be something else going on; and if this is in Razor then it's highly likely that your error is in an entirely different spot in the template.
Oh ya. Sorry about that. Here is the full exception:
This is the partial view. We are using the v7 Mentor Web Blocks package. That's why you see references to CurrentBlock. This is on of the block partial view templates.
I can add a breakpoint and step through.
relatedProductIds
will have multiple nodeIds. Everything is fine until I hitUmbraco.TypedContent(relatedProductId)
with an id to a node that is unpublished. Then everything explodes. If I publish the unpublished node, the error goes away. The error will come back if I unpublish the node again. I've tested it with multiple nodes. It isn't just one corrupted node.I get the same exception in the backoffice block preview and on the frontend of the website. I'm pretty confident that it isn't an issue with Web Blocks. It might be interesting to note that I imported all of the content in this site from a v6 version of the site via customized version of the Conveyor package. Conveyor leverages the ContentService and MediaService though. It isn't doing anything strange as far as the content creation goes. Everything else in the site seems to work as well.
I was able to work around the problem. It looks like the overloads for
TypedContent
that take anIEnumerable<string>
or anIEnumerable<int>
don't have any problems. I just refactored the code a bit, so it works like this. I think this is a little bit prettier than what I had anyways.I'd still like to understand what was happening with the
TypedContent
method that takes a single int or a string.The TypedContent with a single integer does return null when the content is not published. However your code does:
And there, you are not testing whether relatedProduct is null. Hence the nullref exception. Should be:
Alternatively, your workaround would work, too -- and I'm pretty sure you don't need the "p != null" test because relatedProducts would not contain nulls.
Huh. I do this a million times a day. Dunno why I didn't see that... For three days in a row... Thanks!
is working on a reply...