I wanna write a Generic AutoMapper's Resolver for changing Model's file path.
Without Generic Resolver, I've written the following resolver :
eg:
public class UserPhotoPathResolver : ValueResolver<User, string>
{
protected override string ResolveCore(User source)
{
var url = new UrlHelper(HttpContext.Current.Request.RequestContext);
return url.Content(string.IsNullOrWhiteSpace(source.PhotoPath)
? StaticVariables.DefaultUserImagePath
: source.PhotoPath);
}
}
Now, I've written the following Resolver :
public class FilePathResolver<T, TProperty> : ValueResolver<T, string> where T : class
{
private readonly Expression<Func<T, TProperty>> _propertyExpression;
public FilePathResolver(Expression<Func<T, TProperty>> propertyExpression)
{
_propertyExpression = propertyExpression;
}
protected override string ResolveCore(T source)
{
Type typeOfEntity = typeof(T);
MemberExpression member = _propertyExpression.Body as MemberExpression;
if (member == null)
throw new ArgumentException(string.Format("Expression '{0}' refers to a method, not a property.", _propertyExpression));
PropertyInfo propInfo = member.Member as PropertyInfo;
if (propInfo == null)
throw new ArgumentException(string.Format("Expression '{0}' refers to a field, not a property.", _propertyExpression));
if (typeOfEntity != propInfo.ReflectedType && !typeOfEntity.IsSubclassOf(propInfo.ReflectedType))
throw new ArgumentException(string.Format("Expresion '{0}' refers to a property that is not from type {1}.", _propertyExpression, typeOfEntity));
string filePath = Convert.ToString(ModelHelpers.GetStringPropertyValue(source, propInfo.Name));
return string.IsNullOrWhiteSpace(filePath)
? string.Empty
: UrlHelpers.GetUrlHelperInstance().Content(filePath);
}
}
public static object GetStringPropertyValue(object src, string propertyName)
{
return src.GetType().GetProperty(propertyName).GetValue(src, null);
}
public static TProperty GetValue<T, TProperty>(T obj, Expression<Func<T, TProperty>> expression) where T : class
{
if (obj == null) return default(TProperty);
Func<T, TProperty> func = expression.Compile();
return func(obj);
}
But FilePathResolver
returns this string MyApp.Classes.Helpers.FilePathResolver%602[MyApp.DAL.ModelName,System.String]
I'm using this resolver as the following :
Mapper.CreateMap<EntityClass, EntityClassModel>()
.ForMember(m => m.ResolvedLogoPath, opt => opt.ResolveUsing(m => new FilePathResolver<EntityClass, string>(p => p.LogoPath)));
How can I do it?
The problem is that wrong ResolveUsing method overload is used.
But you need the following one.
You can fix it by changing mapping configuration in the following way.
Mapper.CreateMap<EntityClass, EntityClassModel>()
.ForMember(m => m.ResolvedLogoPath,
opt => opt.ResolveUsing<FilePathResolver<EntityClass, string>>()
.ConstructedBy(() => new FilePathResolver<EntityClass, string>(p => p.LogoPath)));
Or even like this:
Mapper.CreateMap<EntityClass, EntityClassModel>()
.ForMember(m => m.ResolvedLogoPath,
opt => opt.ResolveUsing(new FilePathResolver<EntityClass, string>(p => p.LogoPath)));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.