2011-06-30 42 views
11

ASP.NET MVC dường như khuyến khích tôi sử dụng các chuỗi được mã hóa cứng để chỉ bộ điều khiển và hành động.Tránh điều khiển mã hóa cứng và tên hành động

Ví dụ, trong một bộ điều khiển:

return RedirectToAction("Index", "Home"); 

hoặc, trong một lần xem:

Html.RenderPartial("Index", "Home"); 

Tôi không muốn chuỗi mã hóa cứng trên tất cả các mã của tôi. Tôi có thể làm gì để tránh điều này?

+1

Không có vấn đề với IMHO này. Tại một số điểm bạn phải nói cho mã để trỏ đến một lớp hoặc chức năng cụ thể. – Timbo

+2

@Badger vấn đề là những gì nếu bạn đổi tên hành động/bộ điều khiển của bạn. Sau đó bạn phải bằng cách nào đó tìm thấy tất cả các chuỗi mã hóa cứng để cập nhật chúng và bạn không thể dựa vào trình biên dịch để cho bạn biết rằng bạn đã bỏ lỡ một cái gì đó. – Dolbz

+1

ReSharper có thể làm cho điều này không thành vấn đề – driushkin

Trả lời

13

Nghe có vẻ như tôi muốn sử dụng chuyển hướng được nhập mạnh mẽ. Tôi đã thực hiện một lớp helper tĩnh gọi RedirectionHelper có phương pháp sau:

public static string GetUrl<T>(Expression<Action<T>> action, RequestContext requestContext, RouteValueDictionary values = null) where T : Controller 
{ 
    UrlHelper urlHelper = new UrlHelper(requestContext); 
    RouteValueDictionary routeValues = ExpressionHelper.GetRouteValuesFromExpression(action); 

    if (values != null) 
     foreach (var value in values) 
      routeValues.Add(value.Key, value.Value); 

    return urlHelper.RouteUrl(routeValues); 
} 

Thông báo trước là bạn sẽ phải sử dụng Microsoft.Web.Mvc thư viện tương lai có sẵn trên NuGet.

Bây giờ, đối với điều khiển của bạn, tạo ra một bộ điều khiển cơ sở rằng tất cả các bộ điều khiển thừa hưởng từ đó có phương pháp này:

protected RedirectResult RedirectToAction<T>(Expression<Action<T>> action, RouteValueDictionary values = null) where T : Controller 
{ 
    return new RedirectResult(RedirectionHelper.GetUrl(action, Request.RequestContext, values)); 
} 

Bây giờ, trong hành động của bạn, tất cả các bạn phải làm là nói:

return RedirectToAction<Controller>(x => x.Index()); 

Tương tự, bạn có thể viết một phương thức mở rộng html có cùng tham số và xây dựng thẻ neo của bạn.

Giống như bạn đã nói ở trên mà bạn muốn, khi bạn thay đổi tên Bộ điều khiển hoặc Hành động, dự án của bạn sẽ bị ngắt tại thời gian biên dịch và cho bạn thấy nơi xảy ra vi phạm. Tuy nhiên, điều này sẽ chỉ xảy ra trong các bộ điều khiển, xem như cách các khung nhìn không biên dịch.

Hy vọng điều này sẽ hữu ích!

+0

Rất tốt :) Tôi đã đăng một giải pháp tương tự vài giây sau đó –

+0

đẹp - tốt hơn nhiều so với việc làm rối tung các mẫu t4 - điều này sẽ khiến tôi thành thật – iwayneo

+0

Lưu ý: Để làm việc ExpressionHelper phải là 'Microsoft.Web.Mvc .Internal.ExpressionHelper', ** not ** 'System.Web.Mvc.ExpressionHelper'. –

5

Nhìn vào T4MVC này tạo ra các lớp học, do đó bạn có thể có những hành động mạnh mẽ gõ và tên điều khiển. Vì nó vẫn chỉ là ánh xạ tới một chuỗi, việc tái cấu trúc sẽ không làm cho tên trong các khung nhìn của bạn cập nhật nếu bạn thay đổi tên bộ điều khiển chẳng hạn.

Sau khi tạo lại, bạn sẽ gặp lỗi biên dịch do các tên biến mất từ ​​các lớp đã tạo của bạn mặc dù vẫn hữu ích trong việc tái cấu trúc và phát hiện các sự cố mà bạn có thể bỏ lỡ bằng cách sử dụng các chuỗi được mã hóa cứng.

3

Không chắc nếu ai đó đã thêm một phương pháp mở rộng cho một trong những dự án liên quan ASP.NET MVC nhưng đây là một đoạn mã mà bạn có thể sử dụng để tạo ra phương pháp mở rộng của riêng bạn:

public RedirectToRouteResult RedirectToAction<TController>(Expression<Action<TController>> action, RouteValueDictionary routeValues) where TController : Controller 
    { 
     RouteValueDictionary rv = Microsoft.Web.Mvc.Internal.ExpressionHelper.GetRouteValuesFromExpression(action); 

     return RedirectToAction((string)rv["Action"], (string)rv["Controller"], routeValues ?? new RouteValueDictionary()); 
    } 

    public ActionResult Index() 
    { 
     return RedirectToAction<DashboardController>(x => x.Index(), null); 
    } 

Không có thông số hợp nhất logic, vì vậy bạn sẽ phải thêm nó theo cách của riêng bạn.

CẬP NHẬT: @ mccow002 đã thêm một giải pháp tương tự vài giây trước tôi, vì vậy tôi nghĩ giải pháp của anh ấy nên được chấp nhận.

0

Tôi biết đây là một chủ đề cũ, nhưng khi tôi đang tìm kiếm một câu trả lời cho ASP.NET 5 chủ đề này lần đầu tiên xuất hiện. Không cần để hardcode nữa, chỉ cần sử dụng nameof

[HttpGet] 
public IActionResult List() 
{ 
    ... 
    return View(); 
} 

[HttpPost] 
public IActionResult Add() 
{ 
    ... 
    return RedirectToAction(nameof(List)); 
} 
+0

Điều này sẽ không hoạt động nếu ai đó ghi đè tên hành động thông qua thuộc tính ActionName, ví dụ: '[ActionName (" NewActionName ")]' –

+0

@DavidSpence Vâng, nó cũng sẽ không hoạt động với bộ điều khiển như vậy, bạn cần triển khai phương thức mở rộng sẽ cắt hậu tố "Bộ điều khiển". Tuy nhiên đó là một cái gì đó. – Serhii

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