2011-09-12 28 views
15

我反覆提出的一個問題是,在用戶運行一些操作(例如單擊「返回...」鏈接或保存)後處理重定向到上一頁他們正在編輯的記錄。一種處理MVC環境中的返回URL的巧妙方法

以前每當我需要知道要返回的頁面時,我都會提供一個returnURL參數給我當前的視圖。

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

這不是處理這種情況一個非常乾淨的方式,因爲有時返回URL中包含的參數,如搜索字符串,等等,這些都包含在URL。

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

而且,這將創建一個問題時,因爲你必須通過所有訪問過的網頁傳遞returnURL用戶可以向前走另一頁回來的頁面與returnURL之前。

僅僅調用瀏覽器的返回功能也不夠,因爲您可能希望頁面刷新,例如,以顯示您剛剛保存在上一頁中的編輯。

所以我的問題是,有沒有人找到一種聰明的方式來處理這種情況,特別是在MVC環境?

注意:我正在使用ASP .NET MVC,所以如果可能的話,我想要回答有關的,但任何想法都是值得歡迎的。

回答

12

設置cookie或使用會話變量有什麼問題?如果您不控制調用您的頁面,則唯一的原因是您的唯一選項是查詢字符串,帖子值或引薦來源。

+1

我想補充一點,我會檢查會話,然後在頁面加載過程的每一次開始時將其銷燬。然後在頁面加載過程結束時進行必要的設置。這種方式只會在需要時設置會話,並且可以在任何頁面上進行普遍檢查... HTH – Don

+0

Cookie與在URL中傳遞參數的工作方式不同。嘗試使用在多個選項卡中打開的具有相同網站的Cookie。 –

+0

會話很有意義,但用戶在同一會話中使用多個瀏覽器選項卡的情況又如何?當切換標籤然後點擊「返回列表」一段時間後會不會導致意外的行爲? – devuxer

1

嘗試註冊一個新的路線,其中的網址是/{controller}/{action}/{id}/returnurl/{*url}然後用RedirectToAction在接受網址作爲參數

+0

這不會工作得很好(在路由中傳遞一個url)。除了OP已經提到的查詢字符串之外,它並沒有什麼不同。 – eglasius

1
Request.UrlReferrer.AbsoluteUri 

的動作,雖然我仍然認爲,你不應該創建你自己的「後退」按鈕。

+0

我不認爲它是創建我自己的「後退」按鈕。我試圖找到一種乾淨的方式來重定向到基於用戶完成他們來到編輯頁面的頁面,即保存更改。使用網址推薦者不適合這種情況,因爲用戶可能已經從此頁面移動到另一頁面並再次返回。 – link664

+0

不應該回到任何以前的頁面重新創建頁面(因爲它重新調用控制器中的Action返回新視圖)? –

+1

@anvarbek - 是的,那正是我的觀點。通過使用新的調用動作來轉到上一頁將重新創建頁面(這是我所追求的)。按下瀏覽器中的「後退」按鈕不會重新撥打電話,而是使用瀏覽器的緩存版本的頁面。 – link664

3

我想我可能會添加我對問題的回答,看看別人是否認爲這是個好主意。

我使用TempViewData簡單地將其通過控制器:

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

,然後訪問它以類似的方式來這(在我的真實版我檢查,關鍵是在TempData,而且returnURL是一個真正的URL):

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

如果需要繼續過去的第一頁變化(即搜索頁面 - >編輯頁面 - >編輯第頁)我重新加入

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

使用攔截器或一個方面:

  1. 截取以某種方式每個請求(例如,@Before方面)並將請求的URL保存到會話中,每次覆蓋該會話
  2. 在您的視圖圖層中,根據需要訪問該會話對象,在您的情況下爲後端鏈接。

這種設計允許您始終擁有最新的可用請求,如果您想使用它。 Here's an example在.NET中編寫方面/攔截器。另外,PostSharp是一個.NET方面的項目。

+0

爲什麼這會降低投票率? – link664

1

目前,一種快速和骯髒的方法已經躲過了我......所以我正在使用一種實用的方法。

在概念層面上,頁面的「back-ability」應該由您當前所在的頁面決定。如果控制器中捕獲的參數通過ViewModel傳遞給View,View可以推斷出它(在大多數情況下)。

例子:

走訪過Foo,我要去Bar查看某些東西,後退按鈕應該回到Foo

控制器

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. 
    } 
} 

圖(局部)// No pun intended... or maybe it was. :)

你BarView現在可以從它的模型解釋它需要回去(U唱歌fooId)。

在您BarView(使用MVC2語法):

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

您可以使用Html.ActionLink爲好。

或者:

您可以繼承一個BaseViewModel,你的ViewModels它可以有一個保護財產returnURL。必要時進行設置。

例子:

在您的視圖模型:

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. 
    } 
} 

上查看:

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

如果不離開頁面並使用JQuery創建對話框/嚮導工作流程,顯示的部分操作可以更好地處理這種情況嗎?

然後,您只需要對對話框上的「完成」按鈕進行響應以刷新原始視圖。

-1
  1. 編碼使用Url.Encode(returnUrl)列入URL的RETURNURL。
  2. 準備重定向時,請使用Url.Decode(returnUrl)並將該值用於實際重定向。
相關問題