I'm using Umbraco v6.1.6 (Assembly version: 1.0.5021.24867) MVC.
I have a datatype which represents a bunch of 1-6 columns, each column has title (textstring), content (richtext) and link (ucomponents url picker). The easiest way for the editor (I think) is to have a tab on the documenttype for each column - I'd love to use Repeatable Custom Content, but it doesn't render very nicely.
So, I have attributes title1, title2, ..., title6, content1 - content6, etc. in my doc type. So in my .cshtml partial view, I'd like to have a helper function like this:
However, I run into all sorts of problems. If title2 is not set, for example, then CurrentPage.title2 is of type DynamicNull rather than an empty string, so I get an exception because RenderColumn "has some invalid arguments".
I know it's not ideal to have six sets of properties like this, but if anyone can suggest a better way I'm all ears! I don't want to use MNTP with a folder of shared column nodes because it's too complex for users - I want a single node to represent a row of columns of content on the page.
I always find working with the Dynamics a bit hard to manage, especially parsing values that return as DynamicXml!
I find casting the values to expected types works best for me to handle nulls, so using the approach below to silently fail the cast:
var title1 = CurrentPage.title1 as string;
Or doing some sort of Type comparison just to be sure it is what your ecpecting e.g.
var content = (CurrentPage.content1 is IHtmlString ? CurrentPage.content1 : new HtmlString(string.Empty);
Then i'd use those on your method as you are guaranteed the correct types. Im not sure if the above code will compile alright, never tested it, just and idea =)
It is a drawback of this MVC approach where loads of logic is unnecessarily in the view and would defo be better served on a controller or service class. Or you could maybe create a whole whack of HtmlExtensions to parse the dynamic values on a CurrentPage to the types you wold expect to follow the old DRY principles.
No idea on a good solution for the doc type layout though bar using nodes and pickers, would be interested to hear how others would approach that.
Thanks for the response. I'd ended up going down the road of your second suggestion with the type comparisons, but as you say, I'm ending up with lots of logic just to call the helper method - which I was hoping to avoid.
OK for anyone else who is interested, here is a solution that works. It's not the most elegant, certainly not as elegant as I'd hoped, so if anyone can help improve on it then I'm all ears.
So I have to call the methods directly. Here is an example of one that, given an Umbraco property as a parameter, safely returns a HtmlString regardless of whether or not that property actually exists on the Umbraco node (which returns the problematic DynamicNull object):
public static HtmlString GetRichText(dynamic item)
{
if (item is DynamicNull) return new HtmlString(string.Empty);
if (item is IHtmlString) return item;
return new HtmlString(string.Empty);
}
If the property is not of the correct type then an empty string is returned (in this case). I've compiled this into a class library, and have set up an alias in the using statement in my .cshtml razor template:
Helper method in cshtml dealing with dynamicnull
Hi all,
I'm using Umbraco v6.1.6 (Assembly version: 1.0.5021.24867) MVC.
I have a datatype which represents a bunch of 1-6 columns, each column has title (textstring), content (richtext) and link (ucomponents url picker). The easiest way for the editor (I think) is to have a tab on the documenttype for each column - I'd love to use Repeatable Custom Content, but it doesn't render very nicely.
So, I have attributes title1, title2, ..., title6, content1 - content6, etc. in my doc type. So in my .cshtml partial view, I'd like to have a helper function like this:
And I could call this like so:
However, I run into all sorts of problems. If title2 is not set, for example, then CurrentPage.title2 is of type DynamicNull rather than an empty string, so I get an exception because RenderColumn "has some invalid arguments".
I know it's not ideal to have six sets of properties like this, but if anyone can suggest a better way I'm all ears! I don't want to use MNTP with a folder of shared column nodes because it's too complex for users - I want a single node to represent a row of columns of content on the page.
Thanks!
David
Hey Dave,
I always find working with the Dynamics a bit hard to manage, especially parsing values that return as DynamicXml!
I find casting the values to expected types works best for me to handle nulls, so using the approach below to silently fail the cast:
Or doing some sort of Type comparison just to be sure it is what your ecpecting e.g.
Then i'd use those on your method as you are guaranteed the correct types. Im not sure if the above code will compile alright, never tested it, just and idea =)
It is a drawback of this MVC approach where loads of logic is unnecessarily in the view and would defo be better served on a controller or service class. Or you could maybe create a whole whack of HtmlExtensions to parse the dynamic values on a CurrentPage to the types you wold expect to follow the old DRY principles.
No idea on a good solution for the doc type layout though bar using nodes and pickers, would be interested to hear how others would approach that.
Cheers
Hi Michael,
Thanks for the response. I'd ended up going down the road of your second suggestion with the type comparisons, but as you say, I'm ending up with lots of logic just to call the helper method - which I was hoping to avoid.
I'll look into the HtmlExtensions idea though...
Cheers,
David
OK for anyone else who is interested, here is a solution that works. It's not the most elegant, certainly not as elegant as I'd hoped, so if anyone can help improve on it then I'm all ears.
Firstly, you can't create an extension method that takes a dynamic parameter: http://stackoverflow.com/questions/15391115/what-causes-extension-methods-cannot-be-dynamically-dispatched-here
So I have to call the methods directly. Here is an example of one that, given an Umbraco property as a parameter, safely returns a HtmlString regardless of whether or not that property actually exists on the Umbraco node (which returns the problematic DynamicNull object):
If the property is not of the correct type then an empty string is returned (in this case). I've compiled this into a class library, and have set up an alias in the using statement in my .cshtml razor template:
So now I can safely call my original Helper method like this:
which is a bit better than having loads of logic in my view.
is working on a reply...