日期时间映射未转换为正确的格式。

huangapple go评论58阅读模式
英文:

Mapping DateTime Not Converting to the Correct Format

问题

在这个映射器中,在映射逻辑中,我将检查属性是否具有CustomDateConvertAttribute属性。如果有,我将调用一个函数将字符串转换为正确的格式:

CreateMap<JToken, ModelOne>()

.ForAllMembers(opt =>
{
    opt.MapFrom(src => src.SelectToken(opt.DestinationMember.Name));
    opt.Condition((src, des, _, _, resolutionContext) =>
    {
        MemberInfo propDestination = opt.DestinationMember;
        string propName = propDestination.Name;

        // 这是我们使用类型映射器修改数据的地方
        if (Attribute.IsDefined(propDestination, typeof(CustomDateConvertAttribute)))
        {
            opt.ConvertUsing(new CustomDateTimeConverter(), src => src.SelectToken(propName).ToString());
        }

        // 映射所有
        return true;
    });
});

这是我在调用的部分:

public class CustomDateTimeConverter : IValueConverter<string, string>
{
    public string Convert(string source, ResolutionContext context)
    {
        DateTime dt;
        try
        {
            dt = DateTime.Parse(source);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            dt = DateTime.ParseExact(source, "dd/MM/yyyy h:mm:ss tt", CultureInfo.InvariantCulture);
        }

        return dt.Year + "-" + dt.Month + "-" + dt.Day + " " + dt.Hour + ":" + dt.Minute + ":" + dt.Second;
    }
}

然而,它没有成功转换。我如何能够将时间格式转换为正确的值?

更新

回答评论中的问题:
我基本上有两个API。一个是向数据库发送所有的POST请求。发布的数据映射到具有三个属性的模型:

public class BaseModel
{
    public int Id { get; set; }
    public string? DataReceived { get; set; }
    public int? Transferred { get; set; } = 0;
}

然后,DataReceived接受strings,但这里大部分数据是JSON

另一个API是将DataReceived传输到第二个数据库中的模型。这就是我使用AutoMapper的时候。

英文:

I have this mapper, and in the logic of mapping I will check if a property has an attibute CustomDateConverAttribute. If it has, I will call a function to Convert the string to the correct Format:

CreateMap&lt;JToken, ModelOne&gt;()

.ForAllMembers(opt =&gt;
{
    opt.MapFrom(src =&gt; src.SelectToken(opt.DestinationMember.Name));
    opt.Condition((src, des, _, _, resolutionContext) =&gt;
    {
        MemberInfo propDestination = opt.DestinationMember;
        string propName = propDestination.Name;

        //this is where we modify data with type mappers
        if (Attribute.IsDefined(propDestination, typeof(CustomDateConvertAttribute)))
        {
            opt.ConvertUsing(new CustomDateTimeConverter(), src =&gt; src.SelectToken(propName).ToString());
        }

        //map all
        return true;
    });
});

And this is what I'm calling:

public class CustomDateTimeConverter : IValueConverter&lt;string, string&gt;
{
    public string Convert(string source, ResolutionContext context)
    {
        DateTime dt;
        try
        {
            dt = DateTime.Parse(source);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            dt = DateTime.ParseExact(source, &quot;dd/MM/yyyy h:mm:ss tt&quot;, CultureInfo.InvariantCulture);
        }

        return dt.Year + &quot;-&quot; + dt.Month + &quot;-&quot; + dt.Day + &quot; &quot; + dt.Hour + &quot;:&quot; + dt.Minute + &quot;:&quot; + dt.Second;
    }
}

However, it's not successfully being converted. How would I be able to convert the time format to the correct value?

UPDATE

To answer the question in the comments:
I basically have 2 APIs. One is all POST requests to a db. The posted data maps to a model of three properties:

public class BaseModel
{
    public int Id { get; set; }
    public string? DataReceived { get; set; }
    public int? Transfered { get; set; } = 0;
}

Then DataReceived accepts strings but majority of the data here is JSON.

The other API is for transferring the DataReceived to models in the second db. That's when I did the AutoMapper.

答案1

得分: 1

The CustomDateTimeConverter 类实现了 IValueConverter&lt;string, string&gt; 接口。由于源值已经是一个字符串,您不需要在字符串类型上指定 IValueConverter 接口。相反,您可以直接实现 IValueConverter&lt;JToken, DateTime&gt; 接口。

public class CustomDateTimeConverter : IValueConverter&lt;JToken, DateTime&gt;
{
    public DateTime Convert(JToken source, ResolutionContext context)
    {
        string sourceValue = source.ToString();

        DateTime dt;
        if (!DateTime.TryParse(sourceValue, out dt))
        {
            dt = DateTime.ParseExact(sourceValue, &quot;dd/MM/yyyy h:mm:ss tt&quot;, CultureInfo.InvariantCulture);
        }

        return dt;
    }
}

ForAllMembers 配置中,您应该使用 opt.MapFrom 来指定映射的源成员,而不是使用 src.SelectToken(opt.DestinationMember.Name)src.SelectToken(opt.DestinationMember.Name) 将始终返回 null,因为 opt.DestinationMember.Name 指的是目标成员的名称,而不是源成员的名称。

CreateMap&lt;JToken, ModelOne&gt;()
    .ForAllMembers(opt =&gt;
    {
        opt.MapFrom(src =&gt; src);
        opt.Condition((src, des, _, _, resolutionContext) =&gt;
        {
            MemberInfo propDestination = opt.DestinationMember;
            string propName = propDestination.Name;

            if (Attribute.IsDefined(propDestination, typeof(CustomDateConvertAttribute)))
            {
                opt.ConvertUsing&lt;CustomDateTimeConverter&gt;();
            }

            return true;
        });
    });
英文:

The CustomDateTimeConverter class implements the IValueConverter&lt;string, string&gt; interface. Since the source value is already a string, you don't need to specify the IValueConverter interface with string types. Instead, you can simply implement the IValueConverter&lt;JToken, DateTime&gt; interface directly.

public class CustomDateTimeConverter : IValueConverter&lt;JToken, DateTime&gt;
{
    public DateTime Convert(JToken source, ResolutionContext context)
    {
        string sourceValue = source.ToString();

        DateTime dt;
        if (!DateTime.TryParse(sourceValue, out dt))
        {
            dt = DateTime.ParseExact(sourceValue, &quot;dd/MM/yyyy h:mm:ss tt&quot;, CultureInfo.InvariantCulture);
        }

        return dt;
    }
}

In the ForAllMembers configuration, you should use opt.MapFrom to specify the source member for mapping, instead of src.SelectToken(opt.DestinationMember.Name). src.SelectToken(opt.DestinationMember.Name) will always return null because opt.DestinationMember.Name refers to the destination member's name, not the source member's name.

CreateMap&lt;JToken, ModelOne&gt;()
    .ForAllMembers(opt =&gt;
    {
        opt.MapFrom(src =&gt; src);
        opt.Condition((src, des, _, _, resolutionContext) =&gt;
        {
            MemberInfo propDestination = opt.DestinationMember;
            string propName = propDestination.Name;

            if (Attribute.IsDefined(propDestination, typeof(CustomDateConvertAttribute)))
            {
                opt.ConvertUsing&lt;CustomDateTimeConverter&gt;();
            }

            return true;
        });
    });

huangapple
  • 本文由 发表于 2023年5月26日 07:54:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76336870.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定