web-dev-qa-db-fra.com

Erreur de validation sur SaveChanges ()

J'ai la méthode d'action suivante dans mon application Web Asp.net mvc: -

[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);
}

qui appelle la méthode suivante: -

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);
    }
}

Ma classe de modèle est la suivante: -

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; }
}

mais si j'appelle la méthode d'action Create, j'obtiendrai l'exception suivante: -

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:

Quelqu'un peut-il conseiller ce qui ne va pas, car je revérifie mon code et tout devrait fonctionner correctement? Merci

23
john Gu

Vous n'avez pas montré la méthode Save() mais si vous pouvez y ajouter du code comme celui-ci, vous obtiendrez une exception qui contient tous les détails que vous recherchez

try
{
    _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;
}
112
qujck

Je sais que la question est ancienne maintenant, mais j'espère que quelqu'un trouvera cela utile aussi.

  1. Très probablement (et en effet, à en juger par vos commentaires) l'erreur était que votre variable ne passe pas la validation du modèle.
  2. L'autre façon de voir les erreurs que vous ne pouviez pas voir ( sans changer le code ) est de regarder l'exception en utilisant la fenêtre QuickWatch. Le problème est que la fenêtre "Afficher les détails" que vous pouvez ouvrir à partir de l'info-bulle d'exception n'affiche pas EntityValidationErrors. Et sans bloc catch, vous n'avez aucune variable d'exception que vous pouvez consulter dans QuickWatch. Heureusement, QuickWatch a des pseudo-variables. Donc, en utilisant la pseudovariable "$ exception", vous pouvez facilement jeter un œil à l'exception non gérée actuelle dans la fenêtre QuickWatch. (Veuillez voir les captures d'écran ci-dessous) - fenêtre Détails de l'exception et fenêtre QuickWatch avec pseudovariable $ exception
6
Roman Lemko

Bien qu'il s'agisse d'un ancien poste, cette approche peut être plus fructueuse!

Crédits

Essayez quelque chose comme ça

        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;
        }
1
singhswat