Reputation: 107
This is basically a continuation of the question: Typeconverter not working for single properties
The original question was not marked answered, but it seemed to be the way forward for a particular scenario in my project especially since all my reading suggests it should really work. I gave it a shot, but came up with the same problem as mentioned in the final comment (no breakpoints are hit or, in my case, no output dumped to the results window). Here's what I'm starting with, stripped down to a basic example for my needs†.
In LINQPad
void Main()
{
var prop = typeof(Request).GetProperty("Names");
var converter = TypeDescriptor.GetConverter(prop.PropertyType.Dump()).Dump();
var value = converter.ConvertFrom("One,Two").Dump();
}
public class Request
{
[TypeConverter(typeof(EnumerableTypeConverter<string>))]
public IEnumerable<string> Names { get; set; }
}
public class EnumerableTypeConverter<T> : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
new { Context = context, SourceType = sourceType }.Dump("CanConvertFrom");
if (sourceType == typeof(string))
return true;
return false;
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
new { Context = context, DestinationType = destinationType }.Dump("CanConvertTo");
return true;
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
new { Context = context, Culture = culture, Value = value }.Dump("ConvertFrom");
var source = value as string;
if (source == null)
return value.ToString();
return source;
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
new { Context = context, Culture = culture, Value = value, DestinationType = destinationType }.Dump("ConvertTo");
var s = value as IEnumerable<string>;
return s != null ? string.Join(",", s) : base.ConvertFrom(context, culture, value);
}
public override bool IsValid(ITypeDescriptorContext context, object value)
{
new { Context = context, Value = value }.Dump("IsValid");
return true;
}
}
The output is
typeof(IEnumerable<String>)
System.Collections.Generic.IEnumerable`1[System.String]
ReferenceConverter
System.ComponentModel.ReferenceConverter
null
This suggests the problem is one of 1) it isn't seeing the TypeConverterAttribute
definition, 2) it isn't finding my custom TypeConverter
, or 3) it can't create it and silently fails. All of them seem unlikely, but clearly the result doesn't lie. Thus, something in my understanding is amiss. When I directly instantiated an instance, I did not encounter any exceptions.
var testConverter = new EnumerableTypeConverter<string>().Dump();
EnumerableTypeConverter<String>
UserQuery+EnumerableTypeConverter`1[System.String]
For grins and giggles, I tried the non-generic approach
[TypeConverter(typeof(EnumerableStringConverter))]
public IEnumerable<string> Names { get; set; }
public class EnumerableStringConverter : TypeConverter
{
// -- same implementation as EnumerableTypeConverter<T> --
}
but received the same outcome. What am I missing here?
† The code will read through a file containing property names and associated values. Next it will look for the matching property by name and set the value via the converter. Some of the real values are JSON arrays, but I was taking small steps to validate what I was doing prior to creating the full solution of returning a deserialized JSON array into the matching property.
Upvotes: 0
Views: 900
Reputation: 1915
You set converter to the property therefore you should get converter for this property not for type IEnumerable<string>
.
static void Main(string[] args)
{
var properties = TypeDescriptor.GetProperties(typeof(Request));
var propItem = properties["Names"];
var converter = propItem.Converter;
// converter has type {EnumerableTypeConverter<string>}
}
Upvotes: 2