简体   繁体   English

使用 AutoMapper 用空值替换空字符串

[英]Replacing empty strings with nulls with AutoMapper

I am using AutoMapper to map DTOs to entities.我正在使用 AutoMapper 将 DTO 映射到实体。 Also, my WCF services are being consumed by SAP.此外,SAP 正在使用我的 WCF 服务。

The issue is that SAP sends me empty strings instead of nulls (that is, "" instead of null ).问题是 SAP 向我发送空字符串而不是空字符串(即""而不是null )。

So I basically need to go through every field of the DTO I am receiving, and replace empty strings by nulls.所以我基本上需要遍历我收到的 DTO 的每个字段,并用空值替换空字符串。 Is there an easy way to accomplish this with AutoMapper?有没有一种简单的方法可以使用 AutoMapper 完成此操作?

Consider value transform construction for mapper profile考虑映射器配置文件的值转换构造

 CreateMap<Source, Destination>()
.AddTransform<string>(s => string.IsNullOrEmpty(s) ? null : s);

This construction will transform all 'string' type members and if they null or empty replace with null此构造将转换所有“字符串”类型成员,如果它们为 null 或为空,则替换为 null

Depends on what you are after - if there are string fields for which you would like to preserve the empty string and not convert to null, or you want to threat all of them the same.取决于您的追求 - 如果有您想要保留空字符串而不是转换为 null 的字符串字段,或者您想以相同的方式威胁所有这些字段。 The provided solution is if you need to threat them all the same.提供的解决方案是,如果您需要同样威胁他们。 If you want to specify individual properties for which the empty to null conversion should happen, use ForMemeber() instead of ForAllMembers.如果要指定应发生空到空转换的单个属性,请使用 ForMemeber() 而不是 ForAllMembers。

Convert all solution:转换所有解决方案:

namespace Stackoverflow
{
    using AutoMapper;
    using SharpTestsEx;
    using NUnit.Framework;

    [TestFixture]
    public class MapperTest
    {
        public class Dto
        {
            public int Int { get; set; }
            public string StrEmpty { get; set; }
            public string StrNull { get; set; }
            public string StrAny { get; set; }
        }

        public class Model
        {
            public int Int { get; set; }
            public string StrEmpty { get; set; }
            public string StrNull { get; set; }
            public string StrAny { get; set; }
        }

        [Test]
        public void MapWithNulls()
        {
            var dto = new Dto
                {
                    Int = 100,
                    StrNull = null,
                    StrEmpty = string.Empty,
                    StrAny = "any"
                };

            Mapper.CreateMap<Dto, Model>()
                  .ForAllMembers(m => m.Condition(ctx =>
                                                  ctx.SourceType != typeof (string)
                                                  || ctx.SourceValue != string.Empty));

            var model = Mapper.Map<Dto, Model>(dto);

            model.Satisfy(m =>
                          m.Int == dto.Int
                          && m.StrNull == null
                          && m.StrEmpty == null
                          && m.StrAny == dto.StrAny);
        }
    }
}

You can just define string mapping like this:您可以像这样定义字符串映射:

cfg.CreateMap<string, string>()
    .ConvertUsing(s => string.IsNullOrWhiteSpace(s) ? null : s);

You can be specific with the properties too.您也可以对属性进行具体说明。

cfg.CreateMap<Source, Dest>()()
    .ForMember(destination => destination.Value, opt => opt.NullSubstitute(string.Empty)));

Remember if you are using ReverseMap() place it in the very last something like following,请记住,如果您使用ReverseMap()将其放在最后的位置,如下所示,

cfg.CreateMap<Source, Dest>()()
    .ForMember(destination => destination.Value, opt => opt.NullSubstitute(string.Empty)))
    .ReverseMap();;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM