保存更改时的验证错误

27

我在我的Asp.net MVC Web应用程序中有以下的Action方法:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(SDJoin sdj, FormCollection formValues)
{
    Try
    {
        //code goes here
        repository.InsertOrUpdateSD(sdj.StorageDevice, User.Identity.Name, assetid);
        repository.Save();
    }
    catch (Exception ex)
    {
        //code goes here
    }
    PopulateViewBagData();
    return View(sdj);
}

调用以下方法:

public void InsertOrUpdateSD(TMSStorageDevice sd, string username, long assetid)
{
    var resource = entities.Resources.AsNoTracking().SingleOrDefault(a => a.RESOURCEID == assetid);
    if (sd.TMSStorageDeviceID == default(int))
    {
        // New entity
        int technologyypeID = GetTechnologyTypeID("Storage Device");
        Technology technology = new Technology
        {
            IsDeleted = true,
            IsCompleted = false,
            TypeID = technologyypeID,
            Tag = "SD" + GetTagMaximumeNumber2(technologyypeID).ToString(),
            StartDate = DateTime.Now,
            IT360ID = assetid
        };

        InsertOrUpdateTechnology(technology);
        Save();

        sd.TMSStorageDeviceID = technology.TechnologyID;
        tms.TMSStorageDevices.Add(sd);
    }
}

我的模型类如下:

public partial class TMSStorageDevice
{
    public int TMSStorageDeviceID { get; set; }
    public string Name { get; set; }
    public Nullable<decimal> size { get; set; }
    public int RackID { get; set; }
    public string CustomerName { get; set; }
    public string Comment { get; set; }
    public byte[] timestamp { get; set; }

    public virtual Technology Technology { get; set; }
    public virtual TMSRack TMSRack { get; set; }
}

但是如果我调用Create操作方法,将会出现以下异常:

System.Data.Entity.Validation.DbEntityValidationException was caught
  HResult=-2146232032
  Message=Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
  Source=EntityFramework
  StackTrace:
       at System.Data.Entity.Internal.InternalContext.SaveChanges()
       at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
       at System.Data.Entity.DbContext.SaveChanges()
       at TMS.Models.Repository.Save() in c:\Users\Administrator\Documents\Visual Studio 2012\Projects\TMS\TMS\Models\Repository.cs:line 1926
       at TMS.Controllers.StorageDeviceController.Create(SDJoin sdj, FormCollection formValues) in c:\Users\Administrator\Documents\Visual Studio 2012\Projects\TMS\TMS\Controllers\StorageDeviceController.cs:line 160
  InnerException:

请问有人可以指出问题所在吗?我已经仔细检查了代码,一切都应该正常运行吧? 谢谢。


你有没有“查看EntityValidationErrors属性的详细信息”? - Mansfield
它显示了一个错误,具有以下描述:“System.Data.Entity.Validation.DbEntityValidationResult”。 - John John
1
查看“ValidationErrors”属性应该能告诉您问题的具体原因。 - Mansfield
1
在你的方法 InsertOrUpdateSD 中捕获对象 DbEntityValidationException,这将帮助你找到验证错误。 - Codes with Hammer
我捕获了DbEntityValidationException,它显示以下内容: 对象引用未设置为对象的实例。位于TMS.Controllers.StorageDeviceController.Create(SDJoin sdj,FormCollection formValues)中,在c:\ Users \ Administrator \ Documents \ Visual Studio 2012 \ Projects \ TMS \ TMS \ Controllers \ StorageDeviceController.cs: line 218 在lambda_method(Closure,ControllerBase,Object []), 在System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller,Object [] parameters) - John John
显示剩余4条评论
3个回答

134
你没有展示Save()方法,但是如果你可以在其中添加像这样的代码, 你就会得到一个包含你所寻找的所有细节的异常。
try
{
    this.context.SaveChanges();
}
catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
{
    Exception raise = dbEx;
    foreach (var validationErrors in dbEx.EntityValidationErrors)
    {
        foreach (var validationError in validationErrors.ValidationErrors)
        {
            string message = string.Format("{0}:{1}", 
                validationErrors.Entry.Entity.ToString(),
                validationError.ErrorMessage);
            // raise a new exception nesting
            // the current instance as InnerException
            raise = new InvalidOperationException(message, raise);
        }
    }
    throw raise;
}

2
谢谢兄弟。今天你节省了我很多时间。如果没有你的答案,这不会那么容易。 - Pankaj Upadhyay
1
我通常不会只为了说谢谢而写评论,但这一次我会例外。非常感谢!你救了我脱离大麻烦 :) @qujck - Koray Durudogan
1
我赞同@KorayDurudogan所说的话。这非常有帮助。 - dionysus
1
非常感谢!我已经第二次使用这个了! - ChaseHardin
1
非常出色的回答!!否则我将无法在千年中找到错误!!点赞 - BILAL AHMAD
显示剩余2条评论

8

我知道这个问题已经很久了,但是我希望有人也能发现这个有用的东西。

  1. 最有可能(并且根据您的评论来判断),错误在于您的变量未通过模型验证。
  2. 另一种查看错误信息的方法(无需更改代码)是使用 QuickWatch 窗口查看异常。问题在于从异常工具提示打开的“查看详细信息”窗口不显示 EntityValidationErrors。而没有 catch 块,您就没有任何异常变量可在 QuickWatch 中查看。幸运的是,QuickWatch 有 PseudoVariables。 因此,使用“$exception”伪变量可以轻松地在 QuickWatch 窗口中查看当前未处理的异常。(请参见下面的截图) 异常详细信息窗口$exception 伪变量的 QuickWatch 窗口

这个想法解决了我的问题。 - lava

1

虽然这是一篇旧文章,但这种方法可能更加有效!

来源

尝试像这样做

        try
        {
            pcontext.SaveChanges();
        }
       catch (System.Data.Entity.Infrastructure.DbUpdateConcurrencyException ex)
        {             
             Console.WriteLine(ex.InnerException);
        }
        catch (System.Data.Entity.Core.EntityCommandCompilationException ex)
        {
          Console.WriteLine(ex.InnerException);
        }
        catch (System.Data.Entity.Core.UpdateException ex)
        {
         Console.WriteLine(ex.InnerException);
        }

        catch (System.Data.Entity.Infrastructure.DbUpdateException ex) //DbContext
        {
            Console.WriteLine(ex.InnerException);
        }

        catch (Exception ex)
        {
            Console.WriteLine(ex.InnerException);
            throw;
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接