我有一个在asp.net 4和sql server 2008 R2中开发的网站。 问题非常复杂。 我在db中有一个数据时间偏移UTC的字段(例如2015-09-30 18:24:53.1498113 +02:00)。 随机(我认为当应用程序池重新启动时)此值在.net中查询后返回损坏,如下所示: 30/09/2015 18:21:00 +02:00 +02:00 时间偏移重复2次!
所以,当我在c#中解析日期时,显然我收到一个错误“字符串未被识别为有效的DateTime”。
如果我回收池applcation页面工作正常
为什么呢?这是一个错误?你见过类似的问题吗?
非常感谢
答案 0 :(得分:2)
今天我们也遇到过这种情况 - 我第一次见到它。这绝对不是Alex的错误,它是一个强类型的DateTimeOffset,带有沼泽标准.ToString(),它将偏移量加两次。它只发生在我们的一个Web服务器上,如果我们启动它,我预计它会消失。我肯定明确地为ToString提供一个字符串格式可以防止它再次出现,并且可能会出现某种类型的操作系统级别的损坏,因为我已经看到默认格式随操作系统升级而变化(在这种情况下可能会赢得'当我们踢它时,我会得到修复。)
答案 1 :(得分:2)
我们在IIS上托管的asp.net-mvc应用程序(.NET 4.5)中观察到了相同的行为。其中一个服务器在这个看似无害的代码中从razor cshtml中的模型序列化DateTimeOffset值时开始生成重复的偏移量(几周没有部署版本):
@Html.HiddenFor(m => m.CreateDate)
<span>@Model.CreateDate</span>
在这两个地方都生成了重复的偏移量,如2017-11-20 12:34 +01:00 +01:00。 重新启动IIS池解决了这个问题,但我不知道将来如何避免它。
答案 2 :(得分:1)
在我们的一项WCF服务中观察到类似的行为-我们的特定情况是使用Newtonsoft.Json从传入请求中反序列化了DateTimeOffset值,并使用DateTimeOffset.ToString()将其转换为字符串,最后得到的字符串表示形式如下所示
public class EditProfileController : Controller
{
private readonly ApplicationDbContext db;
private object _context;
public EditProfileController(ApplicationDbContext Db)
{
db = Db;
}
public IActionResult Index()
{
List<ApplicationUser> listdata = db.Users
.Select(user => new ApplicationUser()
{
Id = user.Id,
UserName = user.UserName,
NormalizedUserName = user.NormalizedUserName,
Email = user.Email
// Add the remainder properties
}).ToList();
return View(listdata);
}
[HttpGet]
public ActionResult Edit(string id)
{
//Get user and return the Edit View
ApplicationUser user = db.Users.Where(u => u.Id == id)
.Select(u => new ApplicationUser()
{
Id = u.Id,
UserName = u.UserName,
NormalizedUserName = u.NormalizedUserName,
Email = u.Email
// Add the remainder properties
}).FirstOrDefault();
return View(user);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(ApplicationUser listdata)
{
if (ModelState.IsValid)
{
db.Entry(listdata).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(listdata);
}
public async Task<IActionResult> Delete(int? id)
{
if (id == null)
{
return NotFound();
}
var user = await db.Users
.FirstOrDefaultAsync(m => m.Id == id);
if (user == null)
{
return NotFound();
}
return View(user);
}
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
var user = await db.Users.FindAsync(id);
db.Users.Remove(user);
await db.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
}
我们的第一个假设显然是这是我们代码中的错误-它始终是您的代码,对吧?但是,我们在结束时非常详尽地跟踪了执行情况,并且找不到自己可能导致此问题的任何可能的方式-很难相信,看来MM/dd/yyyy 12:00:00 AM -04:00 -04:00
的结果实际上只是在返回那个服务器上的字符串格式。
导致最终错误的特定字符串转换发生在内部框架中,因此我们只是换掉了转换方式,因此我们现在使用显式字符串格式。没有确认是否可行。我们的替换实现如下所示-
DateTimeOffset.ToString
我们的短期解决方案是重新启动IIS应用程序池-两次都遇到该问题后,该问题立即停止出现。
答案 3 :(得分:1)
这是由于DateTimeOffset的ToString()方法中的竞争条件引起的。之所以引起竞争,是因为在构建模式字符串时,代码直接针对dateTimeOffsetPattern成员起作用。模式字符串是短日期和长时间模式的串联。有些文化在长时间模式中包含偏移量,因此代码会对此进行检查。在字符串中不包含偏移量的情况下,它将连接偏移量格式,如下所示:
if (!foundZ) {
dateTimeOffsetPattern = dateTimeOffsetPattern + " zzz";
}
根据执行顺序,有时它会执行两次或在一个线程中执行,而不是在另一个线程中执行。
此问题已在.Net Framework的较新版本中修复,但可以通过提供自己的格式字符串来解决。
答案 4 :(得分:-1)
当我们尝试解析使用DateTimeOffset.toString()值转换的字符串时,会发生同样的问题。 ADO.Net客户端转换中的DateTimeOffset.toString()返回具有重复Offset值的无效DateTimeOffset格式。我们停止了DateTimeOffset的字符串转换,并开始直接使用DateTimeOffset对象。