I use Mapster with version 7.3.0 and .Net 7.0.1
I have two classes.
public class Entity
{
public Guid Id { get; set; }
public string Content { get; set; } = default!;
public string Note { get; set; } = default!;
public CultureInfo CultureInfo { get; set; } = default!;
}
public class Dto
{
[Required, StringLength(64)]
public string Id { get; set; } = default!;
[Required, StringLength(4096)]
public string Content { get; set; } = default!;
[Required, StringLength(1024)]
public string Note { get; set; } = default!;
[Required]
public string CultureName { get; set; } = default!;
}
And with mapster config
TypeAdapterConfig<Dto, Entity>.NewConfig()
.Map(entity => entity.CultureInfo, dto => CultureInfo.GetCultureInfo(dto.CultureName));
TypeAdapterConfig<Entity, Dto>.NewConfig()
.Map(dto => dto.CultureName, entity => entity.CultureInfo.Name);
Now execute this code
//Mapster configuration is applied.
var dto = new Dto
{
Id = Guid.NewGuid().ToString(),
Content = "this is a test content",
Note = "for test",
CultureName = "zh-CN"
};
var mLocal = dto.Adapt<Entity>();
var mLocal = dto.Adapt<Entity>();
throws a Mapster.CompileException: Error while compiling.
Mapster.CompileException: Error while compiling
Mapster.CompileException
Error while compiling
source=MindOcean.Models.Common.MessageTemplateLocalizerDto
destination=MindOcean.Data.Entities.MessageTemplateLocalizer
type=Map
at Mapster.TypeAdapterConfig.CreateMapExpression(CompileArgument arg)
at Mapster.TypeAdapterConfig.CreateMapExpression(TypeTuple tuple, MapType mapType)
at Mapster.TypeAdapterConfig.CreateDynamicMapExpression(TypeTuple tuple)
at Mapster.TypeAdapterConfig.<GetDynamicMapFunction>b__66_0[TDestination](TypeTuple tuple)
at Mapster.TypeAdapterConfig.<>c__DisplayClass55_0`1.<AddToHash>b__0(TypeTuple types)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at Mapster.TypeAdapterConfig.AddToHash[T](ConcurrentDictionary`2 hash, TypeTuple key, Func`2 func)
at Mapster.TypeAdapterConfig.GetDynamicMapFunction[TDestination](Type sourceType)
at Mapster.TypeAdapter.Adapt[TDestination](Object source, TypeAdapterConfig config)
at Mapster.TypeAdapter.Adapt[TDestination](Object source)
at MindOcean.Test.UnitTest.MapsterTester.TestTwoWay() in /Test/MapsterTester.cs:line 71
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
Mapster.CompileException
Error while compiling
source=System.Globalization.CultureInfo
destination=System.Globalization.CultureInfo
type=Map
at Mapster.TypeAdapterConfig.CreateMapExpression(CompileArgument arg)
at Mapster.TypeAdapterConfig.CreateInlineMapExpression(Type sourceType, Type destinationType, MapType mapType, CompileContext context, MemberMapping mapping)
at Mapster.Adapters.BaseAdapter.CreateAdaptExpressionCore(Expression source, Type destinationType, CompileArgument arg, MemberMapping mapping, Expression destination)
at Mapster.Adapters.BaseAdapter.CreateAdaptExpression(Expression source, Type destinationType, CompileArgument arg, MemberMapping mapping, Expression destination)
at Mapster.Adapters.ClassAdapter.CreateInlineExpression(Expression source, CompileArgument arg)
at Mapster.Adapters.BaseAdapter.CreateInlineExpressionBody(Expression source, CompileArgument arg)
at Mapster.Adapters.BaseAdapter.CreateExpressionBody(Expression source, Expression destination, CompileArgument arg)
at Mapster.Adapters.BaseAdapter.CreateAdaptFunc(CompileArgument arg)
at Mapster.TypeAdapterConfig.CreateMapExpression(CompileArgument arg)
System.InvalidOperationException
No default constructor for type 'CultureInfo', please use 'ConstructUsing' or 'MapWith'
at Mapster.Adapters.BaseAdapter.CreateInstantiationExpression(Expression source, Expression destination, CompileArgument arg)
at Mapster.Adapters.ClassAdapter.CreateInstantiationExpression(Expression source, Expression destination, CompileArgument arg)
at Mapster.Adapters.BaseAdapter.CreateInstantiationExpression(Expression source, CompileArgument arg)
at Mapster.Adapters.ClassAdapter.CreateInlineExpression(Expression source, CompileArgument arg)
at Mapster.Adapters.BaseAdapter.CreateInlineExpressionBody(Expression source, CompileArgument arg)
at Mapster.Adapters.BaseAdapter.CreateExpressionBody(Expression source, Expression destination, CompileArgument arg)
at Mapster.Adapters.BaseAdapter.CreateAdaptFunc(CompileArgument arg)
at Mapster.TypeAdapterConfig.CreateMapExpression(CompileArgument arg)
No default constructor for type 'CultureInfo', please use 'ConstructUsing' or 'MapWith'
I tried use MapWith and it worked.
TypeAdapterConfig<Dto, Entity>.NewConfig()
.MapWith(dto => new Entity
{
CultureInfo = CultureInfo.GetCultureInfo(dto.CultureName),
Id = Guid.Parse(dto.Id),
Content = dto.Content,
Note = dto.Note,
});
TypeAdapterConfig<Entity, Dto>.NewConfig()
.Map(dto => dto.CultureName, entity => entity.CultureInfo.Name);
I prefer TypeAdapterConfig<Dto, Entity>.NewConfig()
this way. If there are a lot of properties in the Entity
class, and I only need to configure the CultureInfo
property, the configuration of the other properties is unnecessary, so I don't have to write so much unnecessary code.MapWith
is like I'm converting manually and with a lot of unnecessary code.
I want to know is there an another way rather than MapWith
to solve this mapster mapping configuration problem?
Not sure why it does not work, but at least one workaround can be ignoring the member and using after mapping action:
TypeAdapterConfig<Dto, Entity>.NewConfig()
.Ignore(e => e.CultureInfo)
.AfterMapping((d, e) => e.CultureInfo = CultureInfo.GetCultureInfo(d.CultureName));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With