2017-05-11 1 views
2

내 API 끝점을 호출 할 때 쉼표로 구분 된 문자열을 IEnumerable<T>으로 변환하여 URL을 줄이는 간단한 TypeConverter이 있습니다.단일 속성에 대해 Typeconverter가 작동하지 않습니다.

따라서 클라이언트에 설정되어 서버로 전달되는 요청 개체가 있습니다. 따라서 서버에서는 동일한 객체입니다. 내가 [TypeConverter(typeof(EnumerableTypeConverter))] -attribute와 속성을 장식 한 샘플 요청이

public class MyRequest 
{ 
    [TypeConverter(typeof(EnumerableTypeConverter))] 
    public IEnumerable<string> Names {get;set;} 

    [TypeConverter(typeof(EnumerableTypeConverter))] 
    public IEnumerable<Guid> Ids {get;set;} 
} 

같은 것을 볼 수 있었다

public class EnumerableTypeConverter : TypeConverter 
{ 
    private readonly Type _innerType; 
    private readonly MethodInfo _enumerableCastMethodInfo = typeof(Enumerable).GetMethod(nameof(Enumerable.Cast)); 

    public IEnumerableTypeConverter(Type type) 
    { 
     // check if the type is somewhat ienumerable-like 
     if (type.BaseType != null && type.BaseType.IsGenericType && typeof(IEnumerable<>).MakeGenericType(type.BaseType.GetGenericArguments()[0]).IsAssignableFrom(type.BaseType) && type.BaseType.GetGenericArguments().Length == 1) 
     { 
      _innerType = type.BaseType.GetGenericArguments()[0]; 
     } 
     else 
     { 
      throw new ArgumentException("Incompatible type", nameof(type)); 
     } 
    } 

    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) => sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); 
    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) => (destinationType.BaseType != null && typeof(IEnumerable<>).MakeGenericType(destinationType.BaseType.GetGenericArguments()[0]).IsAssignableFrom(destinationType.BaseType)) || base.CanConvertFrom(context, destinationType); 

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) 
    { 
     var source = value as string; 
     if (source == null) 
      return base.ConvertFrom(context, culture, value); 

     var temp = source.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(s => TypeDescriptor.GetConverter(_innerType).ConvertFromInvariantString(s)); 
     var castMethod = _enumerableCastEmthMethodInfo.MakeGenericMethod(_innerType); 
     var casted = castMethod.Invoke(null, new object[] {temp}); 
     return casted; 
    } 

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) 
    { 
     var s = value as IEnumerable<string>; 
     return s != null ? string.Join(",", s) : base.ConvertFrom(context, culture, value); 
    } 
} 

:

이는 형 컨버터는 모습입니다. 그러나 ConvertFrom -method는 호출되지 않습니다. 속성 대신 속성에 속성을 추가하면 제대로 작동합니다.

답변

0

에서 사용되는 TypeConverterAttribute은 기본 클래스 TypeConverter과 다릅니다.

EnumerableTypeConverter을 호출하려면 인스턴스화해야하며 매개 변수없는 생성자가있는 경우에만 자동으로 인스턴스화 할 수 있습니다. 귀하의 경우에는

, 당신은 일반적인 일이 컨버터하는 EnumerableStringConverter과 EnumerableGuidConverter이 있거나 사용할 수 있습니다

public class EnumerableTypeConverter<T> : TypeConverter 
{ 
} 

당신은 다음과 같이 당신의 재산을 장식 할 수 있습니다

public class MyRequest 
{ 
    [TypeConverter(typeof(EnumerableTypeConverter<string>))] 
    public IEnumerable<string> Names {get;set;} 

    [TypeConverter(typeof(EnumerableTypeConverter<Guid>))] 
    public IEnumerable<Guid> Ids {get;set;} 
} 
+0

일반적인 접근 방식을 시도했습니다. 내가 설정 한 브레이크 포인트 중 하나가 맞지 않습니다. (매개 변수없는) 생성자 나 오버라이드 된 메소드에서도 마찬가지입니다. – KingKerosin

관련 문제