2011-09-12 27 views
15

Một vấn đề tôi gặp phải một lần nữa là xử lý chuyển hướng đến trang trước sau khi người dùng chạy một số hành động như nhấp vào liên kết 'Quay lại ...' hoặc lưu bản ghi họ đang chỉnh sửa.Một cách thông minh để xử lý URL trả về trong môi trường MVC

Trước đây bất cứ khi nào tôi cần biết trang nào cần quay lại, tôi sẽ cung cấp thông số returnURL cho chế độ xem hiện tại của mình.

http://blah.com/account/edit/1?returnURL="account/index" 

Đây không phải là cách rất sạch sẽ để xử lý tình huống này, vì đôi khi URL trả về chứa thông số như chuỗi tìm kiếm, v.v ... phải được bao gồm trong URL.

http://blah.com/account/edit/1?returnURL="account/index?search="searchTerm"" 

Ngoài ra, điều này tạo ra một vấn đề khi người dùng có thể đi về phía trước một trang khác trước khi trở lại với trang có returnURL bởi vì bạn phải vượt qua returnURL qua tất cả các trang truy cập.

Chỉ cần gọi chức năng Quay lại của trình duyệt không thực sự đủ, bởi vì bạn có thể muốn trang làm mới, ví dụ: để hiển thị các chỉnh sửa bạn vừa lưu ở trang trước.

Vì vậy, câu hỏi của tôi là, có ai tìm thấy một cách thông minh để xử lý loại tình huống này, cụ thể trong môi trường MVC không?

Lưu ý: Tôi đang sử dụng ASP .NET MVC vì vậy nếu có thể tôi muốn câu trả lời liên quan đến điều đó, tuy nhiên mọi ý tưởng đều được hoan nghênh.

Trả lời

12

Có vấn đề gì với việc đặt cookie hoặc sử dụng biến phiên? Lý do duy nhất bạn sẽ không là nếu bạn không kiểm soát trang gọi vào bạn, trong trường hợp đó, các tùy chọn duy nhất của bạn là chuỗi truy vấn, giá trị bài đăng hoặc liên kết giới thiệu.

+1

Tôi muốn thêm rằng tôi sẽ làm một kiểm tra cho phiên, sau đó phá hủy nó ở mỗi lần bắt đầu quá trình tải trang. Sau đó đặt nếu cần thiết ở cuối quá trình tải trang. Bằng cách này, một phiên sẽ chỉ được đặt nếu cần và có thể được kiểm tra phổ biến trên bất kỳ trang nào ... HTH – Don

+0

Cookie không hoạt động giống như truyền tham số trong URL. Thử sử dụng cookie với cùng một trang web mở trong nhiều tab. –

+0

Phiên làm cho rất nhiều ý nghĩa, nhưng những gì về tình hình mà người dùng đang sử dụng nhiều tab trình duyệt trong cùng một phiên? Điều đó sẽ không gây ra hành vi bất ngờ khi chuyển đổi các tab sau đó nhấp vào "Quay lại Danh sách" một lúc sau? – devuxer

1

Hãy thử đăng ký một con đường mới trong đó url là /{controller}/{action}/{id}/returnurl/{*url} và sau đó sử dụng một RedirectToAction trong hành động mà chấp nhận url như một tham số

+0

Điều đó sẽ không hoạt động tốt (chuyển url trong một tuyến đường). Bên cạnh đó không khác nhiều so với chuỗi truy vấn, đã được OP đề cập. – eglasius

1
Request.UrlReferrer.AbsoluteUri 

mặc dù tôi vẫn muốn lập luận rằng bạn không nên đang tạo nút "quay lại" của riêng bạn.

+0

Tôi không thấy nó khi tạo nút "quay lại" của riêng mình. Tôi đang cố gắng tìm một cách rõ ràng để chuyển hướng đến trang dựa trên người dùng hoàn thành những gì họ đã đến trang chỉnh sửa để thực hiện, tức là lưu thay đổi. Sử dụng Liên kết giới thiệu URL sẽ không phù hợp với tình huống này vì người dùng có thể đã chuyển sang trang khác từ trang này và ngược lại. – link664

+0

không nên quay trở lại trang trước đó tạo lại trang (vì nó làm cho một cuộc gọi mới đến Hành động trong Bộ điều khiển trả về chế độ xem mới)? –

+1

@anvarbek - vâng, đó chính xác là quan điểm của tôi. Chuyển đến trang trước bằng cách sử dụng một lời gọi mới cho hành động sẽ tạo lại trang (đó là những gì tôi đang theo dõi). Nhấn nút 'Quay lại' trong trình duyệt của bạn sẽ không thực hiện cuộc gọi mới nhưng sử dụng phiên bản được lưu trong bộ nhớ cache của trang. – link664

3

Tôi nghĩ tôi có thể thêm câu trả lời cho câu hỏi để xem liệu người khác có nghĩ đó là một ý tưởng hay không.

Tôi chỉ đơn giản là đi qua nó thông qua bộ điều khiển sử dụng TempViewData:

@{ 
    TempData["returnURL"] = Request.Url.AbsoluteUri; 
} 

và sau đó truy cập vào nó trong một cách tương tự như sau (trong phiên bản thật của tôi Tôi kiểm tra rằng chìa khóa là ở TempData và rằng returnURL là một URL thực):

return Redirect(TempData["returnURL"].ToString()); 

Nếu nó cần phải tiếp tục vào quá khứ thay đổi trang đầu tiên (tức là trang tìm kiếm -> chỉnh sửa trang -> chỉnh sửa trang Mục) tôi thêm một lần nữa

TempData["returnURL"] = TempData["returnURL"]; 
1

Sử dụng một đánh chặn hoặc một khía cạnh:

  1. Intercept mỗi yêu cầu ở một số thời trang (ví dụ, một khía cạnh @Before) và lưu URL được yêu cầu vào phiên, ghi đè URL được yêu cầu vào mỗi lần
  2. Trong lớp chế độ xem của bạn, truy cập đối tượng Phiên đó nếu cần, trong trường hợp của bạn cho liên kết ngược.

Loại thiết kế này cho phép bạn luôn có yêu cầu gần đây nhất có sẵn nếu bạn muốn sử dụng. Here's an example để viết một khía cạnh/chặn trong .NET. Additionaly, PostSharp là một dự án khía cạnh .NET.

+0

Tại sao điều này lại được bình chọn? – link664

1

Hiện tại, một phương pháp nhanh chóng và bẩn thỉu đã lẩn tránh tôi ... vì vậy tôi đang sử dụng một phương pháp thiết thực.

Ở cấp độ khái niệm, 'khả năng trở lại' của một trang sẽ được xác định bởi trang bạn hiện đang truy cập. View có thể suy ra điều này (trong hầu hết các trường hợp) nếu các tham số được capture trong Controller được truyền cho nó thông qua ViewModel.

Ví dụ:

Sau khi thăm Foo, tôi sẽ Bar để xem một số nội dung, và nút quay lại nên trở về Foo.

khiển

public ActionResult Foo(string fooId) // using a string for your Id, good idea; Encryption, even better. 
{ 
    FooModel model = new FooModel() { fooId = fooId }; // property is passed to the Model - important. 
    model.Fill(); 
    return View("FooView", model); 
} 

public ActionResult Bar(string fooId, string barId) 
{ 
    BarModel model = new BarModel() { fooId = fooId; barId = barId }; 
    model.Fill() 
    return View("BarView", model) 
} 

ViewModels

public class FooModel 
{ 
    public string fooId { get; set; } 

    public void Fill() 
    { 
     // Get info from Repository. 
    } 
} 

public class BarModel 
{ 
    public string fooId { get; set; } 
    public string barId { get; set; } 

    public void Fill() 
    { 
     // Get info from Repository. 
    } 
} 

View (một phần)// No pun intended... or maybe it was. :)

BarView của bạn bây giờ có thể giải thích từ mô hình của nó, nơi nó cần phải quay trở lại (bạn hát fooId).

On BarView của bạn (sử dụng cú pháp MVC2):

<a href="<%= string.Format("/Foo?fooId={0}", Model.fooId) %>">Back</a> 

Bạn có thể sử dụng Html.ActionLink là tốt.

Hoặc:

Bạn có thể kế thừa ViewModels của bạn từ một BaseViewModel, có thể có một tài sản returnURL bảo vệ. Đặt điều này khi cần thiết.

Ví dụ:

On ViewModel của bạn:

public class BarModel : BaseViewModel 
{ 
    public string fooId { get; set; } 
    public string barId { get; set; } 

    public void Fill() 
    { 
     returnURL = string.Format("/Foo?fooId={0}", fooId) 
     // Get info from Repository. 
    } 
} 

On Xem:

<a href="<%=returnURL %>">Back</a> 
1

Điều này sẽ được xử lý tốt hơn bằng các hành động một phần hiển thị mà không cần rời khỏi trang và sử dụng JQuery để tạo luồng công việc hộp thoại/trình hướng dẫn?

Sau đó, bạn chỉ cần phản ứng với nút 'Hoàn tất' trên hộp thoại để làm mới chế độ xem gốc.

-1
  1. Mã hóa các ReturnURL sử dụng Url.Encode(returnUrl) để đưa vào URL.
  2. Khi sẵn sàng chuyển hướng, hãy sử dụng Url.Decode(returnUrl) và sử dụng giá trị cho chuyển hướng thực tế.
Các vấn đề liên quan