Hi folks, I've been having a go at using Ditto on a project and have been struggling to get any TypeConverters to work. I've tried the example that is detailed here: http://umbraco-ditto.readthedocs.org/en/develop/usage/ and I've found that when if I include the [System.ComponentModel.TypeConverter(typeof(HtmlStringConverter))] attribute on my HtmlString property in my POCO, then the HtmlString comes back as a null, and what's more, I place breakpoints in the TypeConverter and they don't get hit.
Anyone got any pointers on what to look for here?
I'm using Umbraco 7.2.5 and the latest Ditto from nuget. Mapping is working fine with standard string properties.
Hi Lee, thanks for that! However I was experimenting with TypeConverters because I wanted to make one to handle data from Archetype. This was just a crack at geting a simple one to work :). I was trying to get one to work following the same pattern you used here https://gist.github.com/leekelleher/513c48c634fc44729900 . However I found again that it was always coming back as null and not being called.
The typeconverter itself seems to get called and work fine if I do something like:
var blah = model.Content.GetPropertyValue<MyArchtypeModel>();
That hits my TypeConverter and var is populated with an item of that type.
But, if I leave it to ditto to map it, it never gets hit and returns null. :S
The project does actually have AutoFac in it. It's only used in a couple of places at the moment though so shouldn't apply. Another developer set it up though and it's a little bit of black magic wizardry :) for me atm so maybe I'll try connecting a blank umbraco project to the database and see if I can make anything different happen.
But then when I try to do the conversion I get this:
Type {0} has invalid constructor parameters
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: Type {0} has invalid constructor parameters
Source Error:
Line 14: if (!(model.Content is NewsArticleViewModel))
Line 15: {
Line 16: var newsArticle = model.Content.As<NewsArticleViewModel>(); Line 17: model = new RenderModel(newsArticle, model.CurrentCulture);
Line 18: }
With the DittoMultipleMediaPickerConverter (and other built-in converters), they need to have a concrete class to create. Which means that you can't use IEnumerable<T> for the property type. You can use something like List<T>?
Thanks again Lee! You're ridiculously helpful. Yeah I'm keen to have a look at the source when I get a chance to see what's going on in there. I like the idea of converters for all the different datatypes.
I want to revisit this as I think the aforementioned error is highlighting an inconsistency in Ditto's expected behaviour.
It's perfectly possible to do something like this in Ditto. (It's my preference actually since then I can map extension etc).
public class Foo {
public IEnumerable<Image> Images { get; set; }
}
[TypeConverter(typeof(DittoMediaPickerConverter))]
public Image {
public string Url { get; set; }
}
As Lee says we require a concrete type for conversion (In this instance Image) but I'm wondering now whether we should make a special case for IEnumerable and silently create a List<Poco> so that we can use the interface in both setups?
@James @Lee - it would also be worth considering scenarios where you have a model of
[TypeConverter(typeof(DittoMediaPickerConverter))]
public class Image : PublishedContentModel
{
public Image(IPublishedContent content) : base(content)
{
}
[UmbracoProperty(Constants.Conventions.Media.Bytes)]
public int Bytes { get; set; }
[UmbracoProperty(Constants.Conventions.Media.Extension)]
public string Extension { get; set; }
}
But you need to map a property to return an IEnumerable (based on a multiple media picker). A lot of people will end up with this confusion, (esp as the above code is from the Ditto Skrift article) even though it kinda does make sense that the TypeConverter for the image model will not be able to handle returning a collection.
In this scenario something like
[TypeConverter(typeof(DittoMultipleMediaPickerConverter))]
public IEnumerable<IPublishedContent> Images { get; set; }
will work, but it would be nice if there was an elegant way to get back an IEnumerable (or even a List) .
If you use the DittoPickerConverter instead that can handle both collections and single items and give you what you need.
I'm actually quite keen to mark all the other converters internal and only expose the DittoPickerConverter. That actually uses all the others to do the conversion internally anyway. In my Umbraco solutions I have never used the converters. DittoMediaPickerConverter, DittoMultipleMediaPickerConverter, DittoContentPickerConverter
The only thing I worry about is breaking existing solutions as they'd have to rebuild. However, we haven't reached v1 yet.
@James - I tend to only use DittoPickerConverter too. Maybe we could add the Obsolete attribute to them for the next release and mark them as internal (or even remove them - if not needed) in a future release?
Decorating my Image class with DittoPickerConverter was it, thanks guys. That parses an IEnumerable<Image> viewmodel property without any further type converting needed.
I second @Lee's suggestion to mark the other picker converters as Obsolete / eventually remove them from the public API. Also a quick code update on the Ditto Skrift article would be helpful - it will provide a more generic example and save others from making this same mistake.
BTW I'm using Ditflo for my Merchello workshop at the UKFest, so I'd love to get your feedback on my implementation there. Keep up the great work! Ditto rocks.
TypeConverter not being fired
Hi folks, I've been having a go at using Ditto on a project and have been struggling to get any TypeConverters to work. I've tried the example that is detailed here: http://umbraco-ditto.readthedocs.org/en/develop/usage/ and I've found that when if I include the [System.ComponentModel.TypeConverter(typeof(HtmlStringConverter))] attribute on my HtmlString property in my POCO, then the HtmlString comes back as a null, and what's more, I place breakpoints in the TypeConverter and they don't get hit.
Anyone got any pointers on what to look for here?
I'm using Umbraco 7.2.5 and the latest Ditto from nuget. Mapping is working fine with standard string properties.
thanks!
Hi pantryfight,
Thanks for reporting this. The docs are a little out of date, (only because development on Ditto has been fast-moving recently).
The latest version (v0.6.1) has a built-in feature to handle
HtmlString
objects... try removing theTypeConverter
attribute from your property?Cheers,
- Lee
Hi Lee, thanks for that! However I was experimenting with TypeConverters because I wanted to make one to handle data from Archetype. This was just a crack at geting a simple one to work :). I was trying to get one to work following the same pattern you used here https://gist.github.com/leekelleher/513c48c634fc44729900 . However I found again that it was always coming back as null and not being called.
The typeconverter itself seems to get called and work fine if I do something like:
var blah = model.Content.GetPropertyValue<MyArchtypeModel>();
That hits my TypeConverter and var is populated with an item of that type.
But, if I leave it to ditto to map it, it never gets hit and returns null. :S
Thanks heaps for your time Lee!
Hmmm, weird that it isn't calling your TypeConverters. I'm wondering what it could be....
Do you have any DI/IoC containers configured in your web-app? (I recall someone else having an issue with around this)
Thanks,
- Lee
The project does actually have AutoFac in it. It's only used in a couple of places at the moment though so shouldn't apply. Another developer set it up though and it's a little bit of black magic wizardry :) for me atm so maybe I'll try connecting a blank umbraco project to the database and see if I can make anything different happen.
cheers.
Take a quick read over this issue from our GitHub... see if there is anything obvious in there? I think there are issues with Autofac.
https://github.com/leekelleher/umbraco-ditto/issues/63
Cheers,
- Lee
That seems to be it! Legend. I temporarily killed off the offending portions of my TypeConverter is now alive and well.
By the way, any ETA on 0.7.0? :) Love your work.
Ace!
v0.7.0 is due to land tomorrow!!! :-D
Awesome! Can't wait! Thanks Lee.
Hey pantryfight, just to let you know that we've released a new version:
https://github.com/leekelleher/umbraco-ditto/releases/tag/0.7.0
Hi Lee, thanks a lot for that. The new version seems to be playing nice with our Autofac implementation.
On a side note, just wondering what the correct usage of the DittoMultipleMediaPickerConverter is?
Currently, in my model I've got something like this:
But then when I try to do the conversion I get this:
Type {0} has invalid constructor parameters
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: Type {0} has invalid constructor parameters
Source Error:
Line 14: if (!(model.Content is NewsArticleViewModel)) Line 15: { Line 16: var newsArticle = model.Content.As<NewsArticleViewModel>(); Line 17: model = new RenderModel(newsArticle, model.CurrentCulture); Line 18: }
Side note #2.. (sorry!)
What would be the best way to map to a datatype which is of Umbraco.CheckBoxList type?
thanks again!
Hi pantryfight,
With the
DittoMultipleMediaPickerConverter
(and other built-in converters), they need to have a concrete class to create. Which means that you can't useIEnumerable<T>
for the property type. You can use something likeList<T>
?re: "Umbraco.CheckBoxList" ... I'll get back to you on this, (I can't remember the saved data value format at the moment).
Cheers,
- Lee
re: "Umbraco.CheckBoxList", (according to the docs) it uses a CSV of the selected items.
In terms of Ditto, you should be able to map to it as is, (as in you'll get the CSV value) ... to write a custom TypeConverter to split the string.
We could look at adding this to the other built-in converters? (always open to pull-requests if you want to get involved?) ;-)
Cheers,
- Lee
Thanks again Lee! You're ridiculously helpful. Yeah I'm keen to have a look at the source when I get a chance to see what's going on in there. I like the idea of converters for all the different datatypes.
I want to revisit this as I think the aforementioned error is highlighting an inconsistency in Ditto's expected behaviour.
It's perfectly possible to do something like this in Ditto. (It's my preference actually since then I can map extension etc).
As Lee says we require a concrete type for conversion (In this instance
Image
) but I'm wondering now whether we should make a special case forIEnumerable
and silently create aList<Poco>
so that we can use the interface in both setups?@James - it's worth considering, since we've come across devs wanting to use
IEnumerable
a few times now.In my particular circumstance I'm fine with using a List. I'd just thought I had to return IEnumerable after seeing the example from this thread; https://our.umbraco.org/projects/developer-tools/ditto/ditto-feedback/64290-Multiple-media(images)-value-not-getting-in-Model-using-Ditto
Unless you're gonna be adding to that list really it's better to use an
IEnumerable
as the collection cannot then be modified.I'll look into improving the developmental situation for you and others when I can.
@James @Lee - it would also be worth considering scenarios where you have a model of
But you need to map a property to return an IEnumerable (based on a multiple media picker). A lot of people will end up with this confusion, (esp as the above code is from the Ditto Skrift article) even though it kinda does make sense that the TypeConverter for the image model will not be able to handle returning a collection.
In this scenario something like
will work, but it would be nice if there was an elegant way to get back an IEnumerable (or even a List) .
If you use the
DittoPickerConverter
instead that can handle both collections and single items and give you what you need.I'm actually quite keen to mark all the other converters internal and only expose the
DittoPickerConverter
. That actually uses all the others to do the conversion internally anyway. In my Umbraco solutions I have never used the converters.DittoMediaPickerConverter
,DittoMultipleMediaPickerConverter
,DittoContentPickerConverter
The only thing I worry about is breaking existing solutions as they'd have to rebuild. However, we haven't reached v1 yet.
@lee What do you think?
@James - I tend to only use
DittoPickerConverter
too. Maybe we could add theObsolete
attribute to them for the next release and mark them as internal (or even remove them - if not needed) in a future release?I've opened an issue on GitHub: https://github.com/leekelleher/umbraco-ditto/issues/127
Decorating my Image class with
DittoPickerConverter
was it, thanks guys. That parses anIEnumerable<Image>
viewmodel property without any further type converting needed.I second @Lee's suggestion to mark the other picker converters as
Obsolete
/ eventually remove them from the public API. Also a quick code update on the Ditto Skrift article would be helpful - it will provide a more generic example and save others from making this same mistake.BTW I'm using Ditflo for my Merchello workshop at the UKFest, so I'd love to get your feedback on my implementation there. Keep up the great work! Ditto rocks.
is working on a reply...