I'm trying to save data after i edited back to database. The problem is with the file upload. I have to upload new image everytime i want to save edited data otherwise the controller would think that my img property is null. So i rewrite my edit action to like this, hoping it'd use my uploaded image
[HttpPost]
[ValidateAntiForgeryToken]
[ValidateInput(false)]
public ActionResult Edit([Bind(Include = "id,name,info,whatThisTeach,whatToKnow")] Major major, HttpPostedFileBase img)
{
if (ModelState.IsValid)
{
if(img != null)
{
major.img = new byte[img.ContentLength];
img.InputStream.Read(major.img, 0, img.ContentLength);
}
else
{
var m = db.Majors.Find(major.id);
major.img = m.img;
}
db.Entry(major).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View("Details", major);
}
But when i try to edit data without uploading new image, it gave me this error:
System.InvalidOperationException HResult=0x80131509
Message=Attaching an entity of type 'MUC.Models.Major' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate. Source=EntityFramework StackTrace:
at System.Data.Entity.Core.Objects.ObjectContext.VerifyRootForAdd(Boolean doAttach, String entitySetName, IEntityWrapper wrappedEntity, EntityEntry existingEntry, EntitySet& entitySet, Boolean& isNoOperation) at System.Data.Entity.Core.Objects.ObjectContext.AttachTo(String entitySetName, Object entity) at System.Data.Entity.Internal.Linq.InternalSet1.<>c__DisplayClassa.<Attach>b__9() at System.Data.Entity.Internal.Linq.InternalSet
1.ActOnSet(Action action, EntityState newState, Object entity, String methodName) at System.Data.Entity.Internal.Linq.InternalSet1.Attach(Object entity)
1.set_State(EntityState value) at MUC.Controllers.MajorsController.Edit(Major major, HttpPostedFileBase img) in C:\Users\miike\Desktop\MUC\MUC\Controllers\MajorsController.cs:line 101 at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary
at System.Data.Entity.Internal.InternalEntityEntry.set_State(EntityState value) at System.Data.Entity.Infrastructure.DbEntityEntry2 parameters) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary
2 parameters) at System.Web.Mvc.Async.AsyncControllerActionInvoker.b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult2.CallEndDelegate(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase
1.End() at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.b__3d() at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.b__3f()
and here's my Edit view:
@model MUC.Models.Major
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Edit</title>
</head>
<body>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
<script src="~/Scripts/ckeditor/ckeditor.js"></script>
@using (Html.BeginForm("Edit", "Majors", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Major</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.img, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@if (Model.img != null)
{
var base64 = Convert.ToBase64String(Model.img);
var imgsrc = string.Format("data:image/jpg;base64,{0}", base64);
<img src="@imgsrc" /><br/>
<input type="file" id="img" name="img"/>
}
else
{
<input type="file" id="img" name="img"/>
}
@Html.ValidationMessageFor(model => model.img, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.info, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.info, new { htmlAttributes = new { @id = "info", @class = "form-control" } })
@Html.ValidationMessageFor(model => model.info, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.whatThisTeach, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.TextAreaFor(model => model.whatThisTeach, new { htmlAttributes = new { @class = "form-control", @id = "whatThisTeach" } })
<script type="text/javascript">CKEDITOR.replace('whatThisTeach');</script>
@Html.ValidationMessageFor(model => model.whatThisTeach, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.whatToKnow, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.TextAreaFor(model => model.whatToKnow, new { htmlAttributes = new { @class = "form-control", @id = "whatToKnow" } })
<script type="text/javascript">CKEDITOR.replace('whatToKnow');</script>
@Html.ValidationMessageFor(model => model.whatToKnow, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
</body>
</html>