5

Hiện nay tôi có một cấu trúc thư mục như thế này:MVC khu vực Routing - Bộ điều khiển thư mục với Folder

Area (folder) 
- Toolkit (folder) 
    - Controllers (folder) 
     - AdminController.cs 
    - Views (folder) 
     - Admin (folder) 
      - Privledges (folder) 
       - Create.cshtml 
       - Edit.cshtml 
       - Delete.cshtml 

Những dịch để

/Toolkit/{controller}/{action}/{tool}/{id} 

Có một thực tế xấu để thiết lập các hành động cư xử giống như một bộ điều khiển phục vụ một khung nhìn dựa trên tham số chuỗi {tool} và tham số {id} được truyền cho hành động?

Việc thực hiện những gì tôi đang nói về:

private const string FOLDER_PRIVILEGES = "./Privileges/"; 

    public ActionResult Privileges(string tool, string id = "") 
    { 
     dynamic viewModel = null; 
     ToolViews view; // enum for the views 
     // Parse the tool name to get the enum representation of the view requested 
     bool isParsed = Enum.TryParse(tool, out view); 

     if (!isParsed) 
     { 
      return HttpNotFound(); 
     } 

     switch (view) 
     { 
      case ToolViews.Index: 
       viewModel = GetIndexViewModel(); // call a function that gets the VM 
       break; 
      case ToolViews.Edit: 
       viewModel = GetEditViewModelById(int.Parse(id)); // sloppy parse 
       break; 
      default: 
       viewModel = GetIndexViewModel(); 
       break; 
     } 
     // The folder path is needed to reach the correct view, is this bad? 
     // Should I just create a more specific controller even though it would 
     // require making about 15-20 controllers? 
     return View(FOLDER_PRIVILEGES + tool, viewModel); 
    } 

Khi tôi viết một View, tôi phải chắc chắn rằng tên đường dẫn được sử dụng cho các thư mục

@Html.ActionLink("Edit", "./Toolkit/Admin/Priveleges/Edit", "Admin", new { id = item.id }) 

Điều này dường như là một thực tế kém, bởi vì nếu cấu trúc thư mục thay đổi ở tất cả, nó sẽ đòi hỏi nhiều bảo trì.

Tuy nhiên, nếu tôi phải giải quyết các hành động trong bộ điều khiển thì sẽ có nhiều người trong số họ (gần 20 người được thêm vào theo thời gian).

Nếu những gì tôi đang làm là thực hành không tốt, cách tốt nhất để phục vụ tuyến đường như thế này là gì?

/Toolkit/Admin/Privileges/Edit/1 

Tôi muốn tránh làm như sau:

/Toolkit/Admin/CreatePrivileges/1 
/Toolkit/Admin/EditPrivileges/1 
/Toolkit/Admin/DeletePrivileges/1 

Xin vui lòng cho tôi biết nếu tôi không thực hiện bất kỳ nghĩa nào đó, bởi vì tôi có một thời gian khó khăn đặt câu hỏi này vào từ ngữ.

+0

Có lẽ tôi hiểu lầm, nhưng việc sử dụng mẫu của bạn có phải là bạn sẽ tạo ra một hàm riêng biệt để trả về kiểu xem thích hợp tùy thuộc vào 'ToolViews' enum anyways không? Toàn bộ điểm của MVC là quy ước về cấu hình. Vì quy ước trong MVC là một hành động riêng biệt để xử lý từng khả năng riêng biệt, có vẻ như đó là "thực hành tốt nhất" để đi với ví dụ thứ hai của bạn. IE:/Toolkit/Admin/CreatePrivileges/1. –

+0

Tôi đã quyết định rằng nếu tôi muốn một URL tiêu hóa, tôi cần phải chia nhỏ nó thành các bộ điều khiển nhỏ hơn. Nó có thể là một chút khó chịu để có một loạt các bộ điều khiển, nhưng nó tốt hơn so với những gì tôi đã cố gắng làm trước đây. Thay vì làm/Toolkit/Admin/CreatePrivileges/1 Tôi có/Toolkit/Privileges/Create/1. Tôi nhận ra rằng phần/Admin/không thực sự quan trọng với URL khi tôi có nhiều bộ điều khiển nhỏ hơn. –

+0

Vì vậy, tôi nghĩ chúng tôi đồng ý? –

Trả lời

1

Tôi nghĩ bạn đang cố gắng đưa một quy ước vào MVC đi ngược lại ý định căn bản của nó.

Với MVC, bộ điều khiển của bạn là danh từ và hành động của bạn là động từ. Sử dụng ví dụ của bạn, bạn có:

  • Toolkit (danh từ) - Diện tích
    • Admin (? Danh từ) - Tiểu khu vực? < - đây là một trong đó là một chút sôi nổi
      • Ưu đãi (danh từ) - Bộ điều khiển
        • Tạo (verb) - Hành động
        • Chỉnh sửa (verb) - Hành động
        • Xóa (verb) - Hành động

Như bạn có thể thấy, nếu bạn có thể xem xét Toolkit + Admin là khu vực + subarea, hoặc kết hợp chúng thành một khu vực (TookitAdmin), nó sẽ đưa bạn trở lại mục đích ban đầu cho bộ điều khiển và hành động.

Dựa trên nhận xét, có vẻ như bạn có thể đã quyết định đi theo cách này. Nhưng tôi muốn chỉ ra rằng kết luận mà bạn đã đi đến trong một cách vòng quanh là trở lại với nguồn gốc của MVC.

Là một lưu ý phụ, bạn có cân nhắc chuyển sang MVC4 không? Web API của nó cung cấp hỗ trợ tốt hơn cho API RESTful, có vẻ như bạn đang cố gắng truy cập.

+0

Tôi đồng ý. Tôi đã kỳ lạ-ed ra bằng cách sử dụng rất nhiều bộ điều khiển. Đặc biệt là bộ điều khiển với một hành động. Tuy nhiên, sau khi thử nghiệm phương pháp tiếp cận đó thực sự không phải là xấu khi nó là trong khu vực riêng của mình. Tôi đã sử dụng API Web và trải nghiệm đó là điều khiến tôi muốn có URL RESTful hơn. Đáng buồn thay, dự án này đang bị mắc kẹt trong MVC3 trong thời gian này. –

1

Không phải là câu trả lời cho câu hỏi ban đầu, nhưng OP đã yêu cầu một mẫu của một hạn chế Enum thay vì phải kiểm tra enum trong mỗi hành động. tức là:

// Parse the tool name to get the enum representation of the view requested 
bool isParsed = Enum.TryParse(tool, out view); 

if (!isParsed) 
{ 
    return HttpNotFound(); 
} 

Thay vì phải chấp nhận giá trị enum (Công cụ, trong trường hợp này) dưới dạng chuỗi, bạn có thể buộc giá trị đi vào hành động của bạn đã được chọn làm enum thích hợp. Một lợi ích bổ sung cho điều này là khuôn khổ MVC sẽ chăm sóc trả lại phản hồi chính xác (HttpNotFound) trong trường hợp này.

Đây là phương pháp hạn chế của bạn. Nó chấp nhận bất kỳ loại Enum nào. Không cần phải tạo một ràng buộc riêng cho mỗi Enum.

public class EnumConstraint<T> : IRouteConstraint where T : struct 
{ 
    private readonly HashSet<string> enumNames; 
    public EnumConstraint() 
    { 
     string[] names = Enum.GetNames(typeof(T)); 
     this.enumNames = new HashSet<string>(from name in names select name.ToLowerInvariant()); 
    } 

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) 
    { 
     return this.enumNames.Contains(values[parameterName].ToString().ToLowerInvariant()); 
    } 

} 

Sau đó, trong phương pháp RegisterRoutes của bạn (MVC4) hoặc trang global.asax.cs (MVC3), bạn chỉ cần đăng ký tuyến đường của bạn như thế này:

routes.MapRoute(
    url: "/Toolkit/Admin/{Action}/{id}", 
    constraints: new { Action = new EnumConstraint<ToolViews>(), id = @"\d+" } 
); 

Tôi cũng đã thêm một hạn chế số trên Tham số id để giúp bạn phải phân tích cú pháp đó.

Hãy cho tôi biết cách hoạt động của bạn.

+0

Điều này cực kỳ hữu ích. Cảm ơn nhiều! –

+0

@David - Rất vui được trợ giúp –

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