Im developing a web application in c# and it uses entity framework to make a connection to a sql server database. Everything works fine but there is a weird problem when im trying to add an entity, the program throws an exception when the changes in the DB are been committed, so none of them can be saved.
This is the controller code
[HttpPost]
public ActionResult AddEditEntidadFinanciera(AddEditEntidadFinancieraViewModel model)
{
try
{
using (var TransactionScope = new TransactionScope())
{
if (!ModelState.IsValid)
{
TryUpdateModel(model);
PostMessage(MessageType.Error, i18n.ValidationStrings.DatosIncorrectos);
return View(model);
}
sgTabEntidadFinanciera EntidadFinanciera;
sgTabReglaLimite regla;
if (model.EntidadFinancieraId.HasValue)
{
EntidadFinanciera = context.sgTabEntidadFinanciera.Find(model.EntidadFinancieraId.Value);
regla = context.sgTabReglaLimite.FirstOrDefault(x => x.fk_sgTabReglaLimite_sgTabEntidadFinanciera == EntidadFinanciera.PK_EntidadFinanciera);
if (regla == null)
{
regla = new sgTabReglaLimite();
regla.sgTabEntidadFinanciera = EntidadFinanciera;
context.sgTabReglaLimite.Add(regla);
}
}
else
{
EntidadFinanciera = new sgTabEntidadFinanciera();
regla = new sgTabReglaLimite();
regla.sgTabEntidadFinanciera = EntidadFinanciera;
EntidadFinanciera.fk_sgTabEntidadFinanciera_sgTabEstado = ConstantHelpers.ESTADO_SISTEMA_ENTIDAD_ACTIVO;
context.sgTabEntidadFinanciera.Add(EntidadFinanciera);
context.sgTabReglaLimite.Add(regla);
}
EntidadFinanciera.vRazonSocial = model.RazonSocial;
EntidadFinanciera.vDireccion = model.Direccion;
EntidadFinanciera.vRuc = model.Ruc;
EntidadFinanciera.vAcronimo = model.Acronimo;
EntidadFinanciera.fk_sgTabEntidadFinanciera_sgTabServidor = 1;
EntidadFinanciera.vFtp = model.Ftp;
EntidadFinanciera.vPasswordFtp = model.PasswordFtp;
EntidadFinanciera.vRazonSocial = model.RazonSocial;
EntidadFinanciera.vUsuarioFtp = model.UsuarioFtp;
EntidadFinanciera.vVcBin = model.VcBin;
EntidadFinanciera.vVcIPBancaDesarrollo = model.VcIPBancaDesarrollo;
EntidadFinanciera.vVcMascaraCuentaExterna = model.VcMascaraCuentaExterna;
EntidadFinanciera.vVcMascaraCuentaInterna = model.VcMascaraCuentaInterna;
EntidadFinanciera.iLimite = model.Limite;
if (model.Imagen != null && !String.IsNullOrEmpty(model.Acronimo))
{
var fileName = Guid.NewGuid().ToString().Substring(0, 4) + Path.GetFileName(model.Imagen.FileName);
var path = Path.Combine(Server.MapPath(ConstantHelpers.GetRutaImagenLogoEntidadFinanciera()), fileName);
if (!String.IsNullOrEmpty(EntidadFinanciera.vRuta))
{
System.IO.File.Delete(Server.MapPath(EntidadFinanciera.vRuta));
model.Imagen.SaveAs(path);
EntidadFinanciera.vRuta = ConstantHelpers.GetRutaImagenLogoEntidadFinanciera() + fileName;
}
}
//Here is when the exception is thrown
context.SaveChanges();
TransactionScope.Complete();
PostMessage(MessageType.Success);
return RedirectToAction("LstEntidadFinanciera");
}
}
catch (Exception ex)
{
ExceptionGlobokas exceptionGlobokas = new ExceptionGlobokas(ex.Message, log4net.Core.Level.Alert, ex);
InvalidarContext();
PostMessage(MessageType.Error);
model.Fill(CargarDatosContext(), model.EntidadFinancieraId);
TryUpdateModel(model);
return View(model);
}
}
This is the output after the error message is shown
Output
I already checked that my PK has identity enabled in my database, also i verify if there is a problem with entity framework versions in App.config and Web.config, so im not sure what is causing the problem.
EDIT
Here is the InnerException message
InnerExceptionImage
And this is the Stacktrace
at System.Data.Entity.Internal.InternalContext.SaveChanges()
at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
at System.Data.Entity.DbContext.SaveChanges()
at Globokas.SG.Controllers.AdminController.AddEditEntidadFinanciera(AddEditEntidad>FinancieraViewModel model) in D:\TFS_HL\Globokas.SG\Globokas.SG\Globokas.SG\Controllers\AdminController.cs:li>ne 2436
Related
I'm using sagecrmErp2008feeds to the integration with my application. I'm able to create SalesCredit and SalesInvoice data. But I would like to transfer payment data from my application to Sage50.
Which feed Entry should I use for that for payment transfer ? Please see my Invoice code example. I would like to use the same way to transfer payment but I'm not getting feedentry for that. Here I'm using salesInvoiceFeedEntry feed entry.
public IResult<string> CreateSalesInvoice(Sage50Transaction data)
{
var result = new Result<string>();
try
{
var tradingAccount = GetCustomer(data.CustomerGuid);
if (tradingAccount == null)
{
throw new Exception("Customer not found in Sage");
}
var salesInvoice = new salesInvoiceFeedEntry
{
tradingAccount = tradingAccount
};
salesInvoice.reference = data.ReferenceId;
salesInvoice.reference2 = data.OurRef;
salesInvoice.customerReference = data.YourRef;
salesInvoice.netTotal = data.NetSub;
salesInvoice.taxDate = data.TransactionDate;
salesInvoice.date = data.TransactionDate;
salesInvoice.salesInvoiceLines = new salesInvoiceLineFeed();
if (data.Lines != null)
{
foreach (var item in data.Lines)
{
salesInvoice.salesInvoiceLines.Entries.Add(GetInvoiceLineItem(item));
}
}
var invoiceRequest = new SDataRequest(uri.Uri, salesInvoice, Sage.Integration.Messaging.Model.RequestVerb.POST);
invoiceRequest.Username = Username;
invoiceRequest.Password = Password;
salesInvoiceFeedEntry savedSalesInvoice = new salesInvoiceFeedEntry();
invoiceRequest.RequestFeedEntry<salesInvoiceFeedEntry>(savedSalesInvoice);
result.Data = savedSalesInvoice.UUID.ToString();
result.HasData = !string.IsNullOrEmpty(result.Data);
}
catch (Exception ex)
{
result.HasData = false;
result.Data = null;
result.Error = ex;
result.FailMessage = ex.Message;
}
return result;
}
As per my understanding, "payment transfer" is not possible from 3rd party to sage50, as the Sage 50 Accounts does not support this.
I have a project that uses Entity Framework. While calling SaveChanges on my DbEntityValidationException, I get the following exception:
System.Data.Entity.Validation.DbEntityValidationException: 'Validation
failed for one or more entities. See 'EntityValidationErrors' property
for more details.'
This is all fine and dandy, but I don't want to attach a debugger every time this exception occurs. More over, in production environments I cannot easily attach a debugger so I have to go to great lengths to reproduce these errors.
How can I see the details hidden within the DbEntityValidationException?
private void btnCreateLetter_Click(object sender, EventArgs e)
{
using (TransactionScope TS = new TransactionScope())
{
try
{
Letter TblLetter = new Letter();
TblLetter.Subject = txtSubject.Text.Trim();
TblLetter.Abstract = txtAbstract.Text.Trim();
TblLetter.Body = ckeCKEditor.TextEditor.Text.Trim();
{
var LastLetterID = (from Letter in Database.Letters orderby Letter.LetterID descending select Letter).First();
TblLetter.LetterNO = PublicVariable.TodayDate.Substring(0, 4).Substring(2, 2) + PublicVariable.gDetermineJobLevel + "/" + (LastLetterID.LetterID + 1);
}
TblLetter.CreateDate = lblCreateDate.Text;
TblLetter.UserID = PublicVariable.gUserID;
if (rdbClassification.Checked == true)
{
TblLetter.SecurityType = 1;
}
else if (rdbConfidential.Checked == true)
{
TblLetter.SecurityType = 2;
}
else if (rdbSeries.Checked == true)
{
TblLetter.SecurityType = 3;
}
if (rdbActionType.Checked == true)
{
TblLetter.UrgencyType = 1;
}
else if (rdbInstantaneous.Checked == true)
{
TblLetter.UrgencyType = 2;
}
else if (rdbAnnie.Checked == true)
{
TblLetter.UrgencyType = 3;
}
TblLetter.ArchivesType = 1;
if (rdbFollowHas.Checked == true)
{
TblLetter.FollowType = 1;
}
else if (rdbFollowHasnoot.Checked == true)
{
TblLetter.FollowType = 2;
}
if (rdbAttachmentHas.Checked == true)
{
TblLetter.AttachmentType = 1;
}
else if (rdbAttachmentHasnot.Checked == true)
{
TblLetter.AttachmentType = 2;
}
TblLetter.ReadType = 1;
TblLetter.LetterType = 1;
TblLetter.DraftType = 1;
if (rdbResponseDeadlineHas.Checked == true)
{
TblLetter.AnswerType = 1;
TblLetter.AnswerReadLine = String.Format("{0:yyyy/MM/dd}", Convert.ToDateTime(pdpSetResponseDeadline.Value.Year.ToString() +
"/" + pdpSetResponseDeadline.Value.Month.ToString() + "/" + pdpSetResponseDeadline.Value.Day.ToString()));
}
else if (rdbResponseDeadlineHasnot.Checked == true)
{
TblLetter.AnswerType = 2;
}
Database.Letters.Add(TblLetter);
Database.SaveChanges();
if (rdbAttachmentHas.Checked == true)
{
if (lblPath.Text != "")
{
FileStream ObjectFileStream = new FileStream(lblPath.Text, FileMode.Open, FileAccess.Read);
int Lenght = Convert.ToInt32(ObjectFileStream.Length);
byte[] ObjectData;
ObjectData = new byte[Lenght];
string[] strPath = lblPath.Text.Split(Convert.ToChar(#"\"));
ObjectFileStream.Read(ObjectData, 0, Lenght);
ObjectFileStream.Close();
AttachFile TableAttachFile = new AttachFile();
TableAttachFile.FileSize = Lenght / 1024;
TableAttachFile.FileName = strPath[strPath.Length - 1];
TableAttachFile.FileData = ObjectData;
TableAttachFile.LetterID = TblLetter.LetterID;
Database.AttachFiles.Add(TableAttachFile);
Database.SaveChanges();
}
}
TS.Complete();
MessageBox.Show("saved", "ok", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (InvalidCastException ex)
{
MessageBox.Show(ex.ToString());
MessageBoxIcon.Error);
return;
}
}
}
You have to get the validation errors from the db.SaveChanges() method of the DatabaseContext object -- you can't get them where you are.
You can either modify the SaveChanges() method of your database context and wrap it in a try-catch block, or (since the class is partial) you can extend the partial class within your application and just override the SaveChanges() method.
There is a nice blog post about this called Easy way to improve DbEntityValidationException of Entity Framework here.
The essence of it is something like this:
public partial class NorthwindEntities
{
public override int SaveChanges()
{
try
{
return base.SaveChanges();
}
catch (DbEntityValidationException ex)
{
// Retrieve the error messages as a list of strings.
var errorMessages = ex.EntityValidationErrors
.SelectMany(x => x.ValidationErrors)
.Select(x => x.ErrorMessage);
// Join the list to a single string.
var fullErrorMessage = string.Join("; ", errorMessages);
// Combine the original exception message with the new one.
var exceptionMessage = string.Concat(ex.Message, " The validation errors are: ", fullErrorMessage);
// Throw a new DbEntityValidationException with the improved exception message.
throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);
}
}
}
The blogger explains:
That’s it! The rest of your code will automatically use the overridden
SaveChanges so you don’t have to change anything else. From now on,
your exceptions will look like this:
System.Data.Entity.Validation.DbEntityValidationException: Validation
failed for one or more entities. See 'EntityValidationErrors' property
for more details. The validation errors are: The field PhoneNumber
must be a string or array type with a maximum length of '12'; The
LastName field is required.
The DbEntityValidationException also contains the entities that caused
the validation errors. So if you require even more information, you
can change the above code to output information about these entities.
As mention, you need to check on your EntityValidationError when it throws the exception.
You should fix that validation error, instead of asking bypass this exception.
Normally these errors are table allow length, data type, column does not allow null and etc. There will be exact fiend name mention in your exception too.
My objects will not save no matter what I do they will fetch and get info and make a new record but not update.
This is the code that details with getting existing patient and then modifying the record setting the state then calling save change this is cracking my head the last three hours what is going wrong. I was told you had to change the entity state of an object before it would no if to save but when i try to attach it it says its already attached
Appointment _appointment = new Appointment();
int errorCount = 0;
Patient _patient = SourceDal.getPatientByPatientNewId(Convert.ToInt32(txtPatientId.Text));
_patient.SSN = txtSSN.Text;
_patient.FirstName = txtPatientFirstName.Text;
_patient.LastName = txtPatientLastName.Text;
_patient.Middle = txtPatientMiddle.Text;
_patient.AddressOne = txtPatientAddressOne.Text;
_patient.City = txtPatientCity.Text;
_patient.State = txtPatientState.Text;
_patient.ZipCode = txtPatientZip.Text;
_patient.HomePhone = txtPatientHomePhone.Text;
_patient.WorkPhone = txtPatientWorkPhone.Text;
_patient.CellPhone = txtPatientCellPhone.Text;
if (rBtnHomePhone.Checked == true)
// _patient.ApptPhone = txtPatientHomePhone.Text;
if (rBtnHomePhone.Checked == true)
// _patient.ApptPhone = txtPatientHomePhone.Text;
if (rBtnWorkPhone.Checked == true)
// _patient.ApptPhone = txtPatientWorkPhone.Text;
_patient.BirthDate = dtBirthDate.DateTime;
_patient.emailAddress = txtPatientEmail.Text;
_patient.Race = Convert.ToInt32(dpRace.SelectedValue);
_patient.Ethnicity =Convert.ToInt32(dpEthnicity.SelectedValue);
_patient.Language = Convert.ToInt32(dpLanguages.SelectedValue);
if (dpGender.Text == "")
{
dpGender.Focus();
errorCount = 1;
lblGenderRequired.Text = "* Gender is required.";
}
else
{
errorCount = 0;
lblGenderRequired.Visible = false;
}
_patient.Gender = "M";
_patient.PatientID = txtPatientId.Text;
SourceDal.SourceEntities.Patients.Attach(_patient);
SourceDal.SourceEntities.Patients.Context.ObjectStateManager.ChangeObjectState(_patient, EntityState.Modified);
SourceDal.SourceEntities.SaveChanges();
The error I get is
An unhandled exception of type 'System.InvalidOperationException' occurred in System.Data.Entity.dll
Additional information: An entity object cannot be referenced by multiple instances of IEntityChangeTracker.
Edit 2:
Code to show my function getPaitnetByPatineyNewId
public Patient getPatientByPatientNewId(int newId)
{
Patient patient = new Patient();
if (newId == -1)
{
patient = new Patient();
}
else
{
patient = SourceEntities.Patients
.Where(w => w.ID == newId)
.FirstOrDefault();
}
return patient;
}
I think you have some issues with proper separation of concerns within your DAL, but for the short solution, you should only add (and not attach) if it's a new entity
if (_patent.PatentId == 0)
{
_patient.PatientID = txtPatientId.Text; // If you're using an identity column, remove this line. I would also strongly suggest not letting the user change this...
SourceDal.SourceEntities.Patients.Add(_patient);
}
For Anyone else the above scenarios did not work for me so this is what I had to do. I put a flag on my forms isUpdate and check that on the save button then if save call similar to below then if add just call savechanges and its now working thank you for everyone help hope this help someone.
public void SaveProviders(Provider _providers)
{
try
{
using (var ctx = new SMBASchedulerEntities(this.Connectionstring))
{
ctx.Providers.Add(_providers);
ctx.Entry(_providers).State = System.Data.Entity.EntityState.Modified;
ctx.SaveChanges();
}
}
catch (DbEntityValidationException e)
{
foreach (var eve in e.EntityValidationErrors)
{
Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
eve.Entry.Entity.GetType().Name, eve.Entry.State);
foreach (var ve in eve.ValidationErrors)
{
Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
ve.PropertyName, ve.ErrorMessage);
}
}
throw;
}
}
So I am developing a web app that generates a PDF contract from a partial view, and then validates the digital signiture. I came accross an example here . The problem is that an exception is thrown when validating the signiture and for the life of me I cant figure out why...
Here is the code :
public async Task<ActionResult> Upload(HttpPostedFileBase FileUpload)
{
ActionResult retVal = View();
AspNetUser user = DbCtx.AspNetUsers.Find(User.Identity.GetUserId());
bool signitureIsValid = false;
string blobUrl = string.Empty;
if (FileUpload != null && FileUpload.ContentLength > 0)
{
string fileName = Guid.NewGuid().ToString() + RemoveAllSpaces(FileUpload.FileName);
string filePath = Path.Combine(System.Web.Hosting.HostingEnvironment.MapPath("~/Content/pdfs"), fileName);
FileUpload.SaveAs(filePath);
List<PdfSignature> signatures = new List<PdfSignature>();
using (var doc = new PdfDocument(filePath))
{
var form = (PdfFormWidget) doc.Form;
int count = 0;
try
{
count = form.FieldsWidget.Count;
}
catch
{
count = 0;
}
for (int i = 0; i < count; ++i)
{
var field = form.FieldsWidget[i] as PdfSignatureFieldWidget;
if (field != null && field.Signature != null)
{
PdfSignature signature = field.Signature;
signatures.Add(signature);
}
}
}
PdfSignature signatureOne = signatures[0];
try
{
signitureIsValid = signatureOne.VerifySignature(); // HERE SHE BLOWS !
if (signitureIsValid)
{
blobPactUrl = await BlobUtil.BasicStorageBlockBlobOperationsAsync(System.IO.File.ReadAllBytes(filePath));
if (!string.IsNullOrEmpty(blobPactUrl))
{
ApplicantInfo info = DbCtx.ApplicantInfoes.FirstOrDefault(x => x.UserId == user.Id);
info.URL = blobUrl;
info.SignatureIsValid = true;
info.ActivationDate = DateTime.Now;
info.ActiveUntill = DateTime.Now.AddYears(1);
DbCtx.Entry(info).State = System.Data.Entity.EntityState.Modified;
DbCtx.SaveChanges();
retVal = RedirectToAction("Publications");
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
System.IO.File.Delete(filePath);
}
}
return retVal;
}
Here is an image of
what it looks like when I'm debuging:
I have checked the signiture and it is valid and cerified... I know I'm missing something basic here... Please help me internet!
Just noticed that I posted this. . . Turns out that the problem was due to bug in the package itself. Upon asking the lovely people at E-Iceblue, the bug was recreated, solved and a new version of Spire.PDF was up on nuget within a week.
great job E-Iceblue, it worked fine :)
public ReturnMessage EditCategories(Category objCategory)
{
ReturnMessage objReturnMessage = new ReturnMessage();
try
{
Category objCategoryNew = db.Categories.Where(x => x.CategoryId == objCategory.CategoryId).FirstOrDefault();
if (objCategoryNew != null)
{
objCategoryNew = objCategory;
db.SaveChanges();
objReturnMessage.isSuccessfull = true;
objReturnMessage.responseMessage = "Successfully updated.";
}
else
{
objReturnMessage.isSuccessfull = false;
objReturnMessage.responseMessage = "Category not present.";
}
}
catch (Exception ex)
{
objReturnMessage.isSuccessfull = false;
objReturnMessage.responseMessage = ex.Message;
}
return objReturnMessage;
}
Everything goes fine there are no exceptions still the data isn't getting updated. I don't know what's the issue. Please help?
The line:
objCategoryNew = objCategory;
will not work out since you change the reference objCategoryNew to objCategory, not the object itself, what you have to do is to assign each property of objCategory to objCategoryNew, something like:
objCategoryNew.Pro1 = objCategory.Pro1;
objCategoryNew.Pro2 = objCategory.Pro2;
....