asp.net – 从数据库加载时,DateTime.Kind设置为未指定,而不是UT
当我创建一个Buyin对象时,来自ASP.NET MVC控制器的响应(返回Json(response,JsonRequestBehavior.AllowGet);)如下所示:
"Buyin": { "Id": 95,"PlayerSessionId": 88,"PlayerId": 45,"PlayerName": "Alan","Amount": 888,"BuyinType": "Credits","Description": null,"Authorized": true,"SignPath": "~/Signs/Buyins95.png","Payment": null,"CreationDate": "/Date(1477242738042)/" }, 如果我在Epoch Converter转换它我得到这个时间:GMT:太阳,2016年10月23日17:12:18.042 GMT 在数据库中查看存储的日期时间似乎是正确的: 95 NULL 1 1 2016-10-23 17:12:18.043 发送响应时,Kind被设置为UTC. 现在我调用一个控制器来获取我的所有数据,并且所有日期都有几个小时添加到它: { "Id": 95,"CreationDate": "/Date(1477267938043)/" } 1477267938043 = GMT:周一,2016年10月24日00:12:18.043 GMT 但是,当我请求此对象时,我可以看到实际对象具有正确的日期设置: 但是Kind被设置为Unspecified,所以我认为这导致了问题. 目前我还没有设置任何全球化设置. 所以基本上我的问题是:当ASP.NET MVC从数据库加载日期时有一种方法告诉服务器加载Kind设置为UTC的日期,因为我认为这是问题? 使用Entity Framework保存和加载数据库. 在接受的答案后更新 接受的答案很棒但是我的日期值已经作为UTC日期存储在数据库中,所以我将GetDateTime修改为: public override DateTime GetDateTime(int ordinal) { var date = base.GetDateTime(ordinal); var utcDate = DateTime.SpecifyKind(date,DateTimeKind.Utc); return utcDate; //return base.GetDateTime(ordinal).ToUniversalTime(); } 解决方法
假设您正在使用EF6,并且您希望将从数据库检索到的任何DateTime值的Kind属性设置为Utc.
已经提出了类似的问题,并且答案倾向于暗示进入 我将提出的解决方案适用于实体和投影查询,方法是在DbDataReader级别执行转换(由此类查询使用). 为此,我们需要一个拦截 abstract class DelegatingDbDataReader : DbDataReader { readonly DbDataReader source; public DelegatingDbDataReader(DbDataReader source) { this.source = source; } public override object this[string name] { get { return source[name]; } } public override object this[int ordinal] { get { return source[ordinal]; } } public override int Depth { get { return source.Depth; } } public override int FieldCount { get { return source.FieldCount; } } public override bool HasRows { get { return source.HasRows; } } public override bool IsClosed { get { return source.IsClosed; } } public override int RecordsAffected { get { return source.RecordsAffected; } } public override bool GetBoolean(int ordinal) { return source.GetBoolean(ordinal); } public override byte GetByte(int ordinal) { return source.GetByte(ordinal); } public override long GetBytes(int ordinal,long dataOffset,byte[] buffer,int bufferOffset,int length) { return source.GetBytes(ordinal,dataOffset,buffer,bufferOffset,length); } public override char GetChar(int ordinal) { return source.GetChar(ordinal); } public override long GetChars(int ordinal,char[] buffer,int length) { return source.GetChars(ordinal,length); } public override string GetDataTypeName(int ordinal) { return source.GetDataTypeName(ordinal); } public override DateTime GetDateTime(int ordinal) { return source.GetDateTime(ordinal); } public override decimal GetDecimal(int ordinal) { return source.GetDecimal(ordinal); } public override double GetDouble(int ordinal) { return source.GetDouble(ordinal); } public override IEnumerator GetEnumerator() { return source.GetEnumerator(); } public override Type GetFieldType(int ordinal) { return source.GetFieldType(ordinal); } public override float GetFloat(int ordinal) { return source.GetFloat(ordinal); } public override Guid GetGuid(int ordinal) { return source.GetGuid(ordinal); } public override short GetInt16(int ordinal) { return source.GetInt16(ordinal); } public override int GetInt32(int ordinal) { return source.GetInt32(ordinal); } public override long GetInt64(int ordinal) { return source.GetInt64(ordinal); } public override string GetName(int ordinal) { return source.GetName(ordinal); } public override int GetOrdinal(string name) { return source.GetOrdinal(name); } public override string GetString(int ordinal) { return source.GetString(ordinal); } public override object GetValue(int ordinal) { return source.GetValue(ordinal); } public override int GetValues(object[] values) { return source.GetValues(values); } public override bool IsDBNull(int ordinal) { return source.IsDBNull(ordinal); } public override bool NextResult() { return source.NextResult(); } public override bool Read() { return source.Read(); } public override void Close() { source.Close(); } public override T GetFieldValue<T>(int ordinal) { return source.GetFieldValue<T>(ordinal); } public override Task<T> GetFieldValueAsync<T>(int ordinal,CancellationToken cancellationToken) { return source.GetFieldValueAsync<T>(ordinal,cancellationToken); } public override Type GetProviderSpecificFieldType(int ordinal) { return source.GetProviderSpecificFieldType(ordinal); } public override object GetProviderSpecificValue(int ordinal) { return source.GetProviderSpecificValue(ordinal); } public override int GetProviderSpecificValues(object[] values) { return source.GetProviderSpecificValues(values); } public override DataTable GetSchemaTable() { return source.GetSchemaTable(); } public override Stream GetStream(int ordinal) { return source.GetStream(ordinal); } public override TextReader GetTextReader(int ordinal) { return source.GetTextReader(ordinal); } public override Task<bool> IsDBNullAsync(int ordinal,CancellationToken cancellationToken) { return source.IsDBNullAsync(ordinal,cancellationToken); } public override Task<bool> ReadAsync(CancellationToken cancellationToken) { return source.ReadAsync(cancellationToken); } public override int VisibleFieldCount { get { return source.VisibleFieldCount; } } } 并构建我们需要的实际类: class UtcDateTimeConvertingDbDataReader : DelegatingDbDataReader { public UtcDateTimeConvertingDbDataReader(DbDataReader source) : base(source) { } public override DateTime GetDateTime(int ordinal) { return DateTime.SpecifyKind(base.GetDateTime(ordinal),DateTimeKind.Utc); } } 一旦我们有了这个,我们需要使用EF interception将其插入EF基础设施. 我们首先创建一个自定义DbCommandInterceptor派生类: class UtcDateTimeConvertingDbCommandInterceptor : DbCommandInterceptor { public override void ReaderExecuted(DbCommand command,DbCommandInterceptionContext<DbDataReader> interceptionContext) { base.ReaderExecuted(command,interceptionContext); if (interceptionContext.Result != null && interceptionContext.Exception == null) interceptionContext.Result = new UtcDateTimeConvertingDbDataReader(interceptionContext.Result); } } 注册它(例如从你的DbContext派生类静态构造函数): public class YourDbContext : DbContext { static YourDbContext() { DbInterception.Add(new UtcDateTimeConvertingDbCommandInterceptor()); } // ... } 我们完成了. 现在,来自数据库的每个DateTime值都将Kind属性设置为Utc. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net-mvc-3 – 使用MVC 3的Knockout java脚本
- asp.net-mvc-4 – Visual Studio 2013 C#Web项目
- asp.net – Intuit合作伙伴平台(IPP)QuickBooks
- ASP.NETCore使用AutoFac依赖注入
- asp.net – Razor视图引擎intellisense无法正常工
- asp.net-mvc – 将脚本放在MVC _layout页面中的位
- .net – Razor RTM中的声明性助手方法
- asp.net – 如何使用resxresourcewriter写入所有
- 从Azure功能调用Asp.Net Web API端点
- 动态加载asp.net网站中的用户控件(ascx)