英文:
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<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;
//this is where we modify data with type mappers
if (Attribute.IsDefined(propDestination, typeof(CustomDateConvertAttribute)))
{
opt.ConvertUsing(new CustomDateTimeConverter(), src => src.SelectToken(propName).ToString());
}
//map all
return true;
});
});
And this is what I'm calling:
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;
}
}
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<string, string>
接口。由于源值已经是一个字符串,您不需要在字符串类型上指定 IValueConverter
接口。相反,您可以直接实现 IValueConverter<JToken, DateTime>
接口。
public class CustomDateTimeConverter : IValueConverter<JToken, DateTime>
{
public DateTime Convert(JToken source, ResolutionContext context)
{
string sourceValue = source.ToString();
DateTime dt;
if (!DateTime.TryParse(sourceValue, out dt))
{
dt = DateTime.ParseExact(sourceValue, "dd/MM/yyyy h:mm:ss tt", CultureInfo.InvariantCulture);
}
return dt;
}
}
在 ForAllMembers
配置中,您应该使用 opt.MapFrom
来指定映射的源成员,而不是使用 src.SelectToken(opt.DestinationMember.Name)
。src.SelectToken(opt.DestinationMember.Name)
将始终返回 null,因为 opt.DestinationMember.Name
指的是目标成员的名称,而不是源成员的名称。
CreateMap<JToken, ModelOne>()
.ForAllMembers(opt =>
{
opt.MapFrom(src => src);
opt.Condition((src, des, _, _, resolutionContext) =>
{
MemberInfo propDestination = opt.DestinationMember;
string propName = propDestination.Name;
if (Attribute.IsDefined(propDestination, typeof(CustomDateConvertAttribute)))
{
opt.ConvertUsing<CustomDateTimeConverter>();
}
return true;
});
});
英文:
The CustomDateTimeConverter
class implements the IValueConverter<string, string>
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<JToken, DateTime>
interface directly.
public class CustomDateTimeConverter : IValueConverter<JToken, DateTime>
{
public DateTime Convert(JToken source, ResolutionContext context)
{
string sourceValue = source.ToString();
DateTime dt;
if (!DateTime.TryParse(sourceValue, out dt))
{
dt = DateTime.ParseExact(sourceValue, "dd/MM/yyyy h:mm:ss tt", 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<JToken, ModelOne>()
.ForAllMembers(opt =>
{
opt.MapFrom(src => src);
opt.Condition((src, des, _, _, resolutionContext) =>
{
MemberInfo propDestination = opt.DestinationMember;
string propName = propDestination.Name;
if (Attribute.IsDefined(propDestination, typeof(CustomDateConvertAttribute)))
{
opt.ConvertUsing<CustomDateTimeConverter>();
}
return true;
});
});
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论