PDA

View Full Version : سوال: عمل Edit در MVC



hastiam
سه شنبه 06 دی 1390, 23:09 عصر
سلام
من وقتی اطلاعاتی رو ویرایش می کنم دکمه ثبت ویرایش رو می زنم گفتم وقتی ویرایش انجام شد پیغام ok بده که این پیغام رو میده و هیچ خطایی هم نداره اما وقتی تو دیتابیس نگاه می کنم اون تغییرات رو اعمال نکرده دلیلش چی می تونه باشه ؟
برای یادگیری mvc از کتاب Pro asp.net mvc framwork که کاملترین کتاب در زمینه یادگیری mvc هست استفاده می کنم . برنامم به این شکله که اول یک entity به نام product ایجاد می کنم :

public class Product {
[HiddenInput(DisplayValue=false)]
public int ProductID { get; set; }
public string Name { get; set; }
[DataType(DataType.MultilineText)]
public string Description { get; set; }
public decimal Price { get; set; }
public string Category { get; set; }
}

یک اینترفیس تعریف می کنم :

public interface IProductRepository {
IQueryable<Product> Products { get; }
void SaveProduct(Product product);
}

یک کلاس به شکل زیر :

public class EFProductRepository : IProductRepository {
private EFDbContext context = new EFDbContext();
public IQueryable<Product> Products {
get { return context.Products; }
}

public void SaveProduct(Product product) {
if (product.ProductID == 0) {
context.Products.Add(product);
}
context.SaveChanges();
}
}

این هم Action :

[HttpPost]
public ActionResult Edit(Product product) {
if (ModelState.IsValid) {
repository.SaveProduct(product);
TempData["message"] = string.Format("{0} has been saved", product.Name);
return RedirectToAction("Index");
} else {
// there is something wrong with the data values
return View(product);
}
}

و در نهایت یک View ساختم این برنامه ای که نوشتم عینا تو کتاب هست برای عمل حذف یا اضافه هیچ مشکلی ندارم اما ویرایش رو تو دیتابیس ثبت نمی کنه. در حالی که وقتی برنامه رو خط به خط اجرا می کنم دقیقا مر حله به مرحله و به ترتیب انجام میشه و در نهایت پیغام ok هم میده ولی تغییرات اعمال نمیشه. :گریه:

alimomen54
جمعه 23 دی 1390, 02:34 صبح
سلام
در Actionesult مربوط به Edit هیچ راهی برای دریافت اطلاعات ویرایش شده از طرف View مشخص نشده است. و رکورد مجددا با همان اطلاعات قبلی که توسط شیئ product جاری پاس شده است Update می شود. یعنی رکورد انتخاب شده صاحب مقادیر جدیدی نشده است تا تغییرات را ذخیره نامید.
این کار معمولا توسط formcollection انجام میشه که شما چنین کاری نکرده اید. یعنی علاوه بر Product که پاس شده است باید اطلاعات View را هم توسط Formcollection ارسال کنید. به جای کل رکورد یا شیئ هم میتوانید فقط ID شیئ انتخاب شده ارسال نمائید.به این مثال توجه کنید:
public ActionResult Edit(int id, FormCollection formValues) {

// Retrieve existing dinner
Dinner dinner = dinnerRepository.GetDinner(id);

// Update dinner with form posted values
dinner.Title = Request.Form["Title"];
dinner.Description = Request.Form["Description"];
dinner.EventDate = DateTime.Parse(Request.Form["EventDate"]);
dinner.Address = Request.Form["Address"];
dinner.Country = Request.Form["Country"];
dinner.ContactPhone = Request.Form["ContactPhone"];

// Persist changes back to database
dinnerRepository.Save();

// Perform HTTP redirect to details page for the saved Dinner
return RedirectToAction("Details", new { id = dinner.DinnerID });
}

موفق باشید

als_1360
دوشنبه 01 اسفند 1390, 10:03 صبح
FormCollection در MVC2 استفاده می شه روشی که دوستمون در بالا گفتن در MVC3 .

Javad_Darvish_Amiry
دوشنبه 01 اسفند 1390, 11:10 صبح
به نظر میرسه شما حالت Add رو با حالت Update اشتباه گرفتید یا کد رو ناقص اینجا گذاشتید. دقت کنید:
public void SaveProduct(Product product) {
if (product.ProductID == 0) {
context.Products.Add(product);
}
context.SaveChanges();
}
خوب اگه آی دی برابر با 0 بود (یعنی شیئ جدیدی هست)، عمل Add رو انجام بده ولی اگه نبود چکار کنه؟ طبیعتا کاری نمیکنه؛ چون ازش نخواستیم کاری کنه! کد رو به این شکل تغییر بدید:

public void SaveProduct(Product product) {
if (product.ProductID == 0) {
context.Products.Add(product);
} else {
context.Entry(product).State = EntityState.Modified;
}
context.SaveChanges();
}


UPDATE:
نیاز به استفاده از FormCollection هم نیست و بایندینگ بصورت خودکار انجام میشه.

روشی که دوستمون در بالا گفتن در MVC3ارتباطی به MVC نداره. مشکل دوستمون در EF بوده.
پاینده باشید.