2012-02-25 29 views
5

Trong ứng dụng của tôi, tham số chuỗi truy vấn key có thể được sử dụng để cấp quyền truy cập cho một số hành động/lượt xem nhất định.
Bây giờ tôi muốn tất cả ActionLinks và Biểu mẫu tự động bao gồm thông số này nếu có trong chuỗi truy vấn hiện tại.ASP.NET MVC: Cách đúng để truyền tham số truy vấn thông qua tất cả ActionLinks

Cách phù hợp để thực hiện việc này là gì?

Tôi đang hỏi đúng cách vì tôi đã thấy một số giải pháp đề xuất thay đổi chế độ xem theo cách này hay cách khác (phương pháp mở rộng thay thế/người trợ giúp, thông số thủ công). Đây không phải là một giải pháp tôi đang tìm kiếm.

UPDATE:
giải pháp cuối cùng (dựa trên anwer MikeSW của): https://gist.github.com/1918893.

+0

này cũng dường như có liên quan: http: // stackoverflow.com/questions/5060346/howto-automatically-add-a-specific-value-from-current-route-to-all-generated-lin – DenNukem

Trả lời

9

Bạn có thể làm điều đó với các tuyến đường nhưng bạn cần thêm một chút cơ sở hạ tầng. Một cái gì đó như thế này

public class RouteWithKey:Route 
{ 
    //stuff omitted 
    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) 
    { 
    values.Add("key", requestContext.HttpContext.Request.QueryString["key"]); 
    var t = base.GetVirtualPath(requestContext, values);   
     return t; 
    } 
} 

Tất nhiên bạn sẽ cần phải lấy chìa khóa từ params yêu cầu và xử lý các trường hợp quan trọng là tham số thứ hai trong truy vấn, nhưng apporach này sẽ tự động thêm chìa khóa để mỗi Utel xây dựng thông qua bình thường như.Tôi chỉ cần sử dụng một tuyến đường tùy chỉnh cho một ứng dụng, cho một mục đích khác nhưng tôi đã thử nghiệm với mã ở trên và nó thêm tham số, vì vậy ít nhất trong dự án của tôi có vẻ hoạt động đúng.

+0

Đây là một ý tưởng tốt thực sự liên quan đến câu hỏi, cảm ơn. Thật không may, nó phá vỡ khi được sử dụng trong ActionLink với các tham số riêng của nó. Nó tạo ra url với '? Key = mykey? Other = myother' vì' ActionLink' không mong đợi '?' Trong 'VirtualPath'. –

+0

Tôi đã cập nhật ví dụ để xử lý trường hợp đó – MikeSW

+0

Hoan hô, điều này thực sự hiệu quả! Cảm ơn rất nhiều. Tôi đã tìm thấy cách dễ dàng hơn mặc dù: thêm khóa/giá trị vào 'giá trị' trước khi gọi' base.GetVirtualPath'. Bạn có thể cập nhật câu trả lời của bạn với điều đó (vì nó là tốt để có giải pháp tốt nhất trong câu trả lời được chấp nhận)? –

0

Xin chào tình huống bạn mô tả, bạn có thể dễ dàng sử dụng cookie. Tạo cookie có khóa tên và giá trị giống như giá trị cho thông số URL chính của bạn. Giờ đây, bạn có thể cung cấp hoặc từ chối quyền truy cập cho người dùng của mình bằng cách sử dụng sự hiện diện hoặc vắng mặt của cookie hợp lệ, thay vì sự hiện diện hoặc vắng mặt của thông số chính.

Bạn có thể truy cập các tập tin cookie sử dụng Response.Cookies

Nếu bạn vẫn muốn thay đổi tất cả các mẫu và những người giúp đỡ ActionLink, sau đó bạn có thể tạo những người giúp đỡ mình, rằng trong nội bộ gọi người giúp đỡ MVC, với tham số chủ chốt thêm, và sử dụng trình trợ giúp tùy chỉnh ở mọi nơi. Hãy xem here để viết người giúp đỡ tùy chỉnh

+0

Cân nhắc "chia sẻ", nơi bạn muốn hiển thị một thư viện ảnh nhất định cho một số những người không được đăng ký trên trang web. Bạn chỉ có thể gửi cho họ một liên kết. Bạn cũng có thể đặt cookie khi họ truy cập lần đầu tiên, nhưng nó làm cho xác thực bảo mật phức tạp hơn (bây giờ chúng tôi kiểm tra chuỗi truy vấn hoặc cookie) và tạo ra sự cố nếu họ thực sự muốn chia sẻ một số liên kết phụ cụ thể với người khác. Ngoài ra không phải ai cũng đã bật cookie. –

+0

Đây không phải là trường hợp sử dụng hiện tại của tôi, nhưng tôi cũng có lý do cho trường hợp hiện tại, vì vậy tôi muốn thực hiện chính xác như được yêu cầu. –

+0

Lưu ý rằng tôi đã đề cập không xem xét người trợ giúp tùy chỉnh (các phương pháp mở rộng thay thế trong câu hỏi), yêu cầu thay đổi đối với chế độ xem. Đã cập nhật câu hỏi để làm rõ hơn. –

-1

Có tham số chuỗi truy vấn kiểm soát ủy quyền là một ý tưởng tồi IMHO. Điều gì ngăn tôi thêm thông số này vào url của tôi không chứa?

Cách ưu tiên để thực hiện ủy quyền là sử dụng vai trò (http://msdn.microsoft.com/en-us/library/system.web.security.roleprovider.aspx).

+2

Tôi biết điều này, tuy nhiên không phải tất cả các trường hợp sử dụng và không phải tất cả các ứng dụng đều yêu cầu mức độ bảo mật đó. Ví dụ: bạn có thể cấp cho ai đó quyền truy cập vào Tài liệu Google của mình bằng url với một khóa cụ thể. –

+0

@JakubKonecki xem xét bảo mật dựa trên năng lực và Waterken http://higherlogics.blogspot.com/2012/01/clavis-web-security-microframework.html –

1

Cách thêm khóa để định tuyến giá trị.

{controller}/{action}/{key}

Bất cứ khi nào một url chứa một chuỗi truy vấn với key = somevalue, url sẽ trông giống như

Home/Index/somevalue,

Bây giờ tất cả các liên kết hành động và url tương đối cũng sẽ bao gồm điều này theo mặc định.

+0

Khóa phải nằm trong chuỗi truy vấn (và tùy chọn), có thể Tôi làm điều đó với các giá trị tuyến đường? Ý tôi là URL dự kiến ​​là 'Home/Index? Key = somevalue'. –

+0

không thể thực hiện điều này bằng các giá trị tuyến đường. Nhưng bạn vẫn có thể định nghĩa khóa là Optional.If bạn muốn có nó trong chuỗi truy vấn thì bạn có thể định nghĩa một phần mở rộng cho ActionLink menthod, nó sẽ gắn thêm các giá trị chuỗi truy vấn (nếu có) trong khi tạo liên kết. – Manas

-1

Điều đơn giản nhất là đưa "chìa khóa" tham số trong tất cả các Url.Action và Html.ActionLink theo cách này:

@Url.Action("MyAction", "MyController", new { key = Request["key"] }) 

nếu Request["key"] trống tham số chuỗi truy vấn sẽ bị bỏ qua.

+0

Tôi đã đề cập rằng đây không phải là câu trả lời tôi đang tìm kiếm trong câu hỏi này. Có khuôn khổ đặc biệt làm cho các mối quan tâm xuyên suốt dễ dàng hơn trong hầu hết các trường hợp ('ActionFilter' vv), tôi chưa sẵn sàng từ bỏ ở đây. –

0

Để làm điều này, tôi đã viết một phần mở rộng cho HtmlHelper được gọi là "ActionLinkBack". Các phương thức soạn các liên kết hành động trở lại cùng một bộ điều khiển một hành động và hợp nhất các giá trị tuyến hiện có với bất kỳ giá trị mới nào được chỉ định.

public static HtmlString ActionLinkBack(this System.Web.Mvc.HtmlHelper htmlHelper, string linkText, object routeValues) 
{ 
    return ActionLinkBack(htmlHelper, linkText, new RouteValueDictionary(routeValues), new RouteValueDictionary()); 
} 

public static HtmlString ActionLinkBack(this System.Web.Mvc.HtmlHelper htmlHelper, string linkText, object routeValues, object htmlAttributes) 
{ 
    return ActionLinkBack(htmlHelper, linkText, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes)); 
} 

public static HtmlString ActionLinkBack(this System.Web.Mvc.HtmlHelper htmlHelper, string linkText, RouteValueDictionary routeValues) 
{ 
    return ActionLinkBack(htmlHelper, linkText, routeValues, new RouteValueDictionary()); 
} 

public static HtmlString ActionLinkBack(this System.Web.Mvc.HtmlHelper htmlHelper, string linkText, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes) 
{ 
    // Build a new dictionary of route values based on the previous set 
    var newRouteValues = new RouteValueDictionary(htmlHelper.ViewContext.RouteData.Values); 

    // Retain current querystring parameters 
    var queryString = htmlHelper.ViewContext.HttpContext.Request.QueryString; 
    if (queryString.Count > 0) 
    { 
     foreach (string key in queryString.Keys) 
     { 
      newRouteValues[key] = queryString[key]; 
     } 
    } 

    // Add and override entries from the list of new route values 
    if (routeValues != null) 
    { 
     foreach (var routeValueItem in routeValues) 
     { 
      newRouteValues[routeValueItem.Key] = routeValueItem.Value; 
     } 
    } 

    return new HtmlString(htmlHelper.ActionLink(linkText, null, newRouteValues, htmlAttributes).ToHtmlString()); 
} 

Trong tái sử dụng "trang hoa" của tôi xem tôi sử dụng các phần mở rộng để soạn, bên cạnh, và các liên kết trang cá nhân theo thời gian:

@Html.ActionLinkBack("Next", new { page = (int)ViewData["Page"] + 1 }, new { @class = "navigationLink" }) 
Các vấn đề liên quan