C# 自动映射-将字符串转换为枚举

C# 自动映射-将字符串转换为枚举,c#,automapper,C#,Automapper,我使用AutoMapper已经有一段时间了,遇到了一个需要将一个对象映射到另一个对象的问题(如下所示) 型号: public Guid guid { get; set; } public string Status { get; set; } 使用DTO传输的数据: public Guid guid { get; set; } public Status Status { get; set; } 枚举将包含: public enum Status { Example, An

我使用AutoMapper已经有一段时间了,遇到了一个需要将一个对象映射到另一个对象的问题(如下所示)

型号:

public Guid guid { get; set; }
public string Status { get; set; }
使用DTO传输的数据:

public Guid guid { get; set; }
public Status Status { get; set; }
枚举将包含:

public enum Status {

    Example,
    AnotherExample,
    PossibleExample

}
我已经设法在模型和DTO之间进行了转换,但是,转换是否能够处理通过模型对象传入的字符串在DTO的枚举中找不到的情况?我尝试过此方法,发现在转换时收到错误:

SomeExample ---> System.ArgumentException: Requested value 'SomeExample' was not found.
   at System.Enum.EnumResult.SetFailure(ParseFailureKind failure, String failureMessageID, Object failureMessageFormatArgument)
   at System.Enum.TryParseEnum(Type enumType, String value, Boolean ignoreCase, EnumResult& parseResult)
   at System.Enum.Parse(Type enumType, String value, Boolean ignoreCase)
   at AutoMapper.Mappers.EnumMapper.Map(ResolutionContext context)
   at AutoMapper.MappingEngine.Map(ResolutionContext context)
传递错误字符串的示例:

{
    "guid": "42c1f9f7-a375-4a65-b883-e6e9717d18fe",
    "Status": "SomeExample"
}
如果我使用Enum.Parse,我会假设如果它不能解析字符串,它会将其默认为Enum中的顶级索引

编辑:这是用于将字符串转换为枚举的映射

CreateMap<Model, Dto>()
               .ForMember(d => d.Status, op => op.MapFrom(o => o.Status));
CreateMap()
.ForMember(d=>d.Status,op=>op.MapFrom(o=>o.Status));

您只需指定自己的自定义冲突解决程序,并确保安全处理

使用AutoMapper配置文件的完整工作示例:

namespace MyProject.Domain.Mapping
{
    public enum Status
    {
        Unknown,
        Example,
        AnotherExample,
        PossibleExample
    }

    public class RecordPost
    {
        public Status Status { get; set; }
    }

    public class RecordDto
    {
        public string Status { get; set; }
    }

    public static class AutoMapperConfiguration
    {
        public static void Configure()
        {
            Mapper.Initialize(cfg =>
            {
                cfg.AddProfile(new RecordProfile());
            });

            Mapper.AssertConfigurationIsValid();
        }
    }

    public class RecordProfile : Profile
    {
        public RecordProfile()
        {
            CreateMap<RecordPost, RecordDto>()
                .ForMember(x => x.Status, opt => opt.MapFrom(src => src.Status.ToString()));

            CreateMap<RecordDto, RecordPost>()
                .ForMember(x => x.Status, opt => opt.ResolveUsing(src =>
                {
                    if (!Enum.TryParse(typeof(Status), src.Status, out var parsedResult))
                        return Status.Unknown;
                    return parsedResult;
                }));
        }
    }
}
名称空间MyProject.Domain.Mapping
{
公共枚举状态
{
不详,
例子,
另一个例子,
可能的例子
}
公营记录站
{
公共状态状态{get;set;}
}
公共类记录
{
公共字符串状态{get;set;}
}
公共静态类自动映射配置
{
公共静态void Configure()
{
Mapper.Initialize(cfg=>
{
AddProfile(newrecordprofile());
});
assertConfigurationsValid();
}
}
公共类RecordProfile:Profile
{
公共档案
{
CreateMap()
.ForMember(x=>x.Status,opt=>opt.MapFrom(src=>src.Status.ToString());
CreateMap()
.ForMember(x=>x.Status,opt=>opt.ResolveUsing(src=>
{
if(!Enum.TryParse(typeof(Status)、src.Status、out var parsedResult))
返回状态。未知;
返回parsedResult;
}));
}
}
}

您是如何实现转换的?您是否使用不匹配的字符串对其进行了测试?您是否应该将该枚举属性设置为空?@OnkelToob我已更新了我的原始问题,以匹配您提出的问题。感谢您的建议,但在尝试实现此功能时,我遇到了
src
的问题,并且无法访问所需的属性。我在这里做错了什么吗?听起来像是这样-如果可以,把问题代码片段放在要点中,然后在这里发布链接。增加了一个完整的例子-你很接近,但你跳过了几个步骤。我知道我错过了一些东西,但我看不到什么。通过比较我的代码和你的代码,我可以看出它应该可以工作,但我根本没有选择使用
src.Status
。我所拥有的只是诸如“值、类型、上下文”等属性。嗨,杰克,主要的问题是你需要两个独立的类。一个用于配置AutoMapper,另一个单独的类继承自定义实际映射的
Profile
。然后在父配置类中使用概要文件的一个实例——这种设计允许您为大型(或模块化)项目拆分映射。
namespace MyProject.Domain.Mapping
{
    public enum Status
    {
        Unknown,
        Example,
        AnotherExample,
        PossibleExample
    }

    public class RecordPost
    {
        public Status Status { get; set; }
    }

    public class RecordDto
    {
        public string Status { get; set; }
    }

    public static class AutoMapperConfiguration
    {
        public static void Configure()
        {
            Mapper.Initialize(cfg =>
            {
                cfg.AddProfile(new RecordProfile());
            });

            Mapper.AssertConfigurationIsValid();
        }
    }

    public class RecordProfile : Profile
    {
        public RecordProfile()
        {
            CreateMap<RecordPost, RecordDto>()
                .ForMember(x => x.Status, opt => opt.MapFrom(src => src.Status.ToString()));

            CreateMap<RecordDto, RecordPost>()
                .ForMember(x => x.Status, opt => opt.ResolveUsing(src =>
                {
                    if (!Enum.TryParse(typeof(Status), src.Status, out var parsedResult))
                        return Status.Unknown;
                    return parsedResult;
                }));
        }
    }
}