2012-03-19 64 views
54

Tôi có một phương pháp chỉnh sửa cơ bản trong bộ điều khiển của tôi chuyển hướng trở lại danh sách cấp cao nhất (“Chỉ mục”) khi chỉnh sửa thành công. Hành vi tiêu chuẩn sau giàn giáo MVC.C# ASP.NET MVC Quay lại trang trước

Tôi đang cố thay đổi phương thức Chỉnh sửa này để chuyển hướng trở lại trang trước đó (không phải chỉ mục). Vì phương thức Chỉnh sửa của tôi không sử dụng tham số đầu vào được ánh xạ mặc định là "id", trước tiên tôi đã thử sử dụng phương thức đó để chuyển vào URL trước đó.

Trong Edit “nhận được” phương pháp của tôi, tôi đã sử dụng dòng này để lấy URL trước và nó làm việc tốt:

ViewBag.ReturnUrl = Request.UrlReferrer; 

sau đó tôi gửi URL trả về này vào Chỉnh sửa “bài” phương pháp bằng cách sử dụng hình thức của tôi thẻ như thế này:

@using (Html.BeginForm(new { id = ViewBag.ReturnUrl })) 

Đây là nơi bánh xe bị rơi. Tôi không thể lấy URL được phân tích cú pháp từ thông số id đúng cách.

*** UPDATE: SOLVED ** *

Sử dụng ví dụ Garry như một hướng dẫn, tôi đã thay đổi thông số của tôi từ "id" thành "ReturnUrl" và sử dụng một ẩn để chuyển tham số của tôi (thay vì thẻ biểu mẫu). Bài học kinh nghiệm: Chỉ sử dụng tham số "id" được sử dụng như thế nào và giữ cho nó đơn giản. Nó hoạt dộng bây giờ. Đây là mã được cập nhật của tôi với ghi chú:

Trước tiên, tôi lấy URL trước đó bằng cách sử dụng Request.UrlReferrer như tôi đã làm lần đầu tiên.

// 
    // GET: /Question/Edit/5 

    public ActionResult Edit(int id) 
    { 
     Question question = db.Questions.Find(id); 
     ViewBag.DomainId = new SelectList(db.Domains, "DomainId", "Name", question.DomainId); 
     ViewBag.Answers = db.Questions 
          .AsEnumerable() 
          .Select(d => new SelectListItem 
          { 
           Text = d.Text, 
           Value = d.QuestionId.ToString(), 
           Selected = question.QuestionId == d.QuestionId 
          }); 
     // Grab the previous URL and add it to the Model using ViewData or ViewBag 
     ViewBag.returnUrl = Request.UrlReferrer; 
     ViewBag.ExamId = db.Domains.Find(question.DomainId).ExamId; 
     ViewBag.IndexByQuestion = string.Format("IndexByQuestion/{0}", question.QuestionId); 
     return View(question); 
    } 

và bây giờ tôi vượt qua các tham số ReturnURL từ Model với phương pháp [HttpPost] sử dụng một lĩnh vực tiềm ẩn trong các hình thức:

@using (Html.BeginForm()) 
{ 
    <input type="hidden" name="returnUrl" value="@ViewBag.returnUrl" /> 
    ... 

Trong phương pháp [HttpPost] chúng tôi kéo các tham số từ lĩnh vực ẩn và chuyển hướng đến nó ....

// 
    // POST: /Question/Edit/5 

    [HttpPost] 
    public ActionResult Edit(Question question, string returnUrl) // Add parameter 
    { 
     int ExamId = db.Domains.Find(question.DomainId).ExamId; 
     if (ModelState.IsValid) 
     { 
      db.Entry(question).State = EntityState.Modified; 
      db.SaveChanges(); 
      //return RedirectToAction("Index"); 
      return Redirect(returnUrl); 
     } 
     ViewBag.DomainId = new SelectList(db.Domains, "DomainId", "Name", question.DomainId); 
     return View(question); 
    } 
+1

Thậm chí nếu bạn không sử dụng 'id', tôi sẽ không sử dụng nó để chuyển URL. Điều đó có vẻ như một hack, và tôi chắc chắn có một cách tốt hơn để làm điều đó. –

+0

Có, Eirc bạn là chính xác. Tôi đã sử dụng một hack xấu xí. Đây là ứng dụng MVC đầu tiên của tôi. Tôi đã thử nhiều thứ và đọc nhiều bài đăng và bản hack là nỗ lực tốt nhất của tôi. Tôi đã sửa nó dựa trên ví dụ của Gary. Cảm ơn, –

Trả lời

44

Tôi giả định (hãy sửa tôi nếu tôi sai) mà bạn muốn hiển thị lại trang chỉnh sửa nếu chỉnh sửa không thành công và thực hiện việc này bạn đang sử dụng một chuyển hướng.

Bạn có thể có nhiều may mắn hơn bằng cách chỉ trả lại chế độ xem thay vì cố gắng chuyển hướng người dùng, theo cách này bạn sẽ có thể sử dụng ModelState để xuất ra bất kỳ lỗi nào.

Edit:

Updated dựa trên phản hồi. Bạn có thể đặt URL trước đó trong viewModel, thêm URL đó vào trường ẩn rồi sử dụng lại trong hành động lưu chỉnh sửa.

Ví dụ:

public ActionResult Index() 
{ 
    return View(); 
} 

[HttpGet] // This isn't required 
public ActionResult Edit(int id) 
{ 
    // load object and return in view 
    ViewModel viewModel = Load(id); 

    // get the previous url and store it with view model 
    viewModel.PreviousUrl = System.Web.HttpContext.Current.Request.UrlReferrer; 

    return View(viewModel); 
} 

[HttpPost] 
public ActionResult Edit(ViewModel viewModel) 
{ 
    // Attempt to save the posted object if it works, return index if not return the Edit view again 

    bool success = Save(viewModel); 
    if (success) 
    { 
     return RedirectToAction(viewModel.PreviousUrl); 
    } 
    else 
    { 
     ModelState.AddModelError("There was an error"); 
     return View(viewModel); 
    } 
} 

Phương pháp BeginForm cho tầm nhìn của bạn không cần phải sử dụng URL trả về này một trong hai, bạn sẽ có thể nhận được ngay với:

@model ViewModel 

@using (Html.BeginForm()) 
{ 
    ... 
    <input type="hidden" name="PreviousUrl" value="@Model.PreviousUrl" /> 
} 

Trở lại với hành động biểu mẫu của bạn đăng lên một URL không chính xác, điều này là do bạn đang chuyển URL dưới dạng thông số 'id', do đó định tuyến tự động định dạng URL của bạn với đường dẫn trả về.

Điều này sẽ không hoạt động vì biểu mẫu của bạn sẽ được đăng lên hành động của trình điều khiển sẽ không biết cách lưu chỉnh sửa. Trước tiên, bạn cần đăng hành động lưu của mình, sau đó xử lý chuyển hướng bên trong nó.

+2

+1. + Thêm nếu tôi có thể. – Fenton

+0

Có, nhưng tôi cần nó để chuyển hướng trở lại trang trước nếu chỉnh sửa thành công. Tôi nghĩ rằng nó không hoạt động vì tôi đã sử dụng "id". Tôi đã thay đổi tham số thành "url" như được hiển thị bên dưới và dường như đã làm việc trong lần thử đầu tiên của tôi nhưng tôi cần thử nghiệm thêm .... giữ và tôi sẽ đăng những gì tôi có. Tôi mới đăng bài trên trang web này và dùng một tic để làm quen với nó. –

+0

Trong trường hợp đó, bạn có thể đặt URL trước đó trong ViewBag khi tải trang Chỉnh sửa ban đầu, sau đó đặt nó vào trường ẩn. Sau đó, bạn có thể truy cập nó như một phần của ViewModel của bạn trong hành động đăng bài và chuyển hướng đến nó. Tôi muốn một cái gì đó như thế này hơn là gửi nó qua querystring. Nếu bạn muốn một ví dụ cho tôi biết. –

Các vấn đề liên quan