2012-05-18 36 views
0

從視圖'x'中,當用戶單擊'編輯項目'時,呈現'編輯'頁面的控制器操作也會檢查用戶該頁面。如何在頁面上顯示友好的錯誤消息並取消控制器動作

我想要做的是檢查這些權限,如果用戶沒有他們,我想在'X'視圖上顯示錯誤消息並取消控制器操作。

現在,我的代碼如下所示:

[HttpPost] 
    public virtual ActionResult EditPage(int? itemId) 
    { 
     var model = new EditPageModel(); 
     if (itemId.HasValue) 
     { 
      var obj = new Item(itemId.Value); 

    // Check for user's edit permission before we do anything else. 

    var request = SecurityRequest.Create(obj, Item_Edit); 
    Request.Execute(() => SecurityManager.ValidatePermissions(request)); 
      if (!request.IsValid(Item_Edit)) 
      { 
       //skip the rest and return error 
       Response.StatusCode = (int)HttpStatusCode.Forbidden; 
       // Need Help Here!!! 
      } 

     // Mode code executes  
     return View(model); 
    } 
+0

對於錯誤信息,不要忘了大的,友好的信件:HTTP://mantia.me/images /dontpanic_large.jpg – SomeKittens

+0

您可否在之前檢查權限而不顯示編輯鏈接?爲什麼讓他們看到它,如果他們不能編輯? – user1166147

+0

根本不顯示編輯鏈接是不可能的。在放置編輯按鈕的視圖中,列出了用戶可以/不能編輯的不同項目。在選擇每個項目後,我們需要確定他是否可以編輯。理想情況下,我們將基於此禁用/啓用「編輯」按鈕,但因爲這需要回撥給控制器,所以我們只是在用戶實際點擊「編輯」按鈕時保存它。 – Trynity

回答

1

你可以做到這一點(這是我在當前項目中使用的一個例子)的一種方法是創建你自己的ActionFilter。這是我的例子:

public class UserAuthenticatedAction : FilterAttribute, IAuthorizationFilter 
{ 
    public void OnAuthorization(AuthorizationContext filterContext) 
    { 
     if (IsContextFromLoginController(filterContext)) 
     { 
      return; 
     } 

     //...Do whatever you need to check. 

     if (userNotAllowed){ 
      SetRedirectToLoginErrorPageForContext(filterContext); 
     } 

     return; 
    } 

    private static void SetRedirectToLoginErrorPageForContext(AuthorizationContext filterContext) 
    { 
     filterContext.Result = new RedirectToRouteResult(
      new RouteValueDictionary 
       { 
        { "controller", "Login" }, 
        { "action", "LoginError" }, 
        { "targeturl" , filterContext.RequestContext.HttpContext.Request.Url.ToString()} } 
       }); 
    } 

    private static bool IsContextFromLoginController(AuthorizationContext filterContext) 
    { 
     var controllerName = GetCurrentControllerName(filterContext); 

     return controllerName.Equals("Login"); 
    } 

    private static string GetCurrentControllerName(AuthorizationContext filterContext) 
    { 
     return filterContext.ActionDescriptor.ControllerDescriptor.ControllerName; 
    } 
} 

要使用此過濾器,在文件的global.asax.cs,我此行Application_Start()

GlobalFilters.Filters.Add(new UserAuthenticatedAction(excludeActions, allowedRoles));

這意味着該屬性被執行每當ActionMethod叫做。基本上它會檢查用戶是否被允許訪問特定網址,如果該用戶不被允許,那麼filterContext將被設置爲將他們重定向回登錄頁面。

我還檢查當前的url是否已經是登錄頁面;如果是這種情況,那麼不要麻煩做安全檢查。

我想根據您的要求,有更多奇特的做法,但上述方法適用於我們的需求。

+0

這是一個很好的答案。我沒有使用ActionFilters,所以這個回覆會激勵我稍後再玩一次goosey。謝謝。 – garfbradaz

+0

同意。這是最好的方式,但它不是我最終使用的。無論如何,我認爲這是'答案'。謝謝。 – Trynity

0

你可以使用一個AJAX請求調用EditPage行動。如果授予權限,它可以返回一個回調以重定向到完整的編輯頁面(對像EditPageView這樣的操作)。否則,可能會返回錯誤消息的回調。

0

您可以隨時重定向到錯誤頁面並顯示相應的消息。

if (!request.IsValid(Item_Edit)) 
{ 
    //skip the rest and return error 
    Response.StatusCode = (int)HttpStatusCode.Forbidden; 
    ViewBag.errorMessage = "Sorry you do not have access to this page"; 
    return View("Error") 
    // Need Help Here!!! 
} 

而且在你的錯誤頁面(應該有一個共享視圖文件夾),您可以添加以下行

@ViewBag.errorMessage 

編輯

如果你不想重定向到錯誤頁面並停留在頁面x上,您可以執行以下操作:

if (!request.IsValid(Item_Edit)) 
{ 
    //skip the rest and return error 
    Response.StatusCode = (int)HttpStatusCode.Forbidden; 
    ModelState.AddModelError("", "Sorry you do not have access to this page"); 
    ModelForPageX modelX = new ModelForPageX(); 
    // do any other setup you need to in order to render page X 
    return View("X",modelX) 

} 

這裏假設你有上頁X 視圖的@Html.ValidationSummary如果沒有添加以下行

@Html.ValidationSummary(true, "Unable to process the requested action:") 
+0

理想情況下,我想避免將用戶重定向到錯誤頁面。 – Trynity

+0

不好意思誤解了原來的問題。 – keshav

相關問題