2011-12-19 30 views
5

Tôi đang sử dụng ASP.NET MVC3 và tôi tự hỏi rằng modelbinder mặc định liên kết với các thuộc tính công khai nhưng không liên kết với các trường công khai.Có một lý do tại sao modelbinder mặc định không liên kết với các trường không?

Thông thường tôi chỉ xác định các lớp mô hình có thuộc tính nhưng đôi khi tôi sử dụng một số lớp được xác định trước có chứa một số trường. Và mọi lúc tôi phải gỡ lỗi và nhớ rằng modelbinder không thích các trường.

Câu hỏi: Lý do đằng sau nó là gì?

Trả lời

0

Có thể lý do bỏ qua các trường là tăng hiệu suất của chất kết dính. Thay vì tìm kiếm tất cả các trường và thuộc tính. Model Binder chỉ tìm kiếm các thuộc tính.

Mặc dù tôi nghĩ Trình mô hình sử dụng bộ nhớ cache để cải thiện hiệu suất.

2

nhưng đôi khi tôi sử dụng một số lớp học được xác định trước, trong đó có một số lĩnh vực

Trong khi tôi không thể trả lời câu hỏi của bạn về lý do chính xác tại sao mô hình mặc định binder chỉ làm việc với tài sản (tôi đoán là nó tôn trọng tốt hơn đóng gói theo cách này và tránh sửa đổi trạng thái bên trong của đối tượng là trường đại diện cho) Tôi có thể nói rằng những gì bạn gọi là các lớp được xác định trước thường là các kiểu xem. Bạn nên luôn sử dụng các mô hình xem đến và đi từ các hành động của bộ điều khiển. Các mô hình khung nhìn đó là các lớp được xác định cụ thể để đáp ứng các yêu cầu của khung nhìn đã cho.

Vì vậy, quay lại điểm chính: các trường được cho là chỉ được sửa đổi từ bên trong lớp đã cho. Chúng không nên được truy cập trực tiếp từ bên ngoài. Chúng đại diện và giữ trạng thái bên trong của lớp. Mặt khác, các thuộc tính là những gì cần được tiếp xúc với thế giới bên ngoài. Hãy tưởng tượng rằng trong tài sản getter/setter bạn đã có một số logic tùy chỉnh. Bằng cách thay đổi trực tiếp trường, logic tùy chỉnh này sẽ bị hỏng và có khả năng đưa đối tượng vào trạng thái không nhất quán.

+1

Ok, nhưng để bạn có các công cụ sửa đổi truy cập. Nếu tôi không muốn một lĩnh vực được thiết lập trực tiếp, tôi chỉ cần khai báo nó là 'private'. Các lớp ViewModel thường chỉ là các datacontainer và hầu hết không chứa nhiều logic - vì vậy tôi nghĩ rằng nó có thể là ok để chỉ sử dụng các trường công khai. – Jan

+0

@Jan, các trường thông thường phải là riêng tư. –

+1

Và thông thường bạn không nên có logic trong getters của tài sản ... – gdoron

0

Mặc địnhModelBinder hiển thị phương thức công khai: DefaultModelBinder.BindModel và một số phương pháp được bảo vệ có sẵn để ghi đè. Tất cả chúng được liệt kê here.

Bên cạnh những mô hình, những phương pháp đề cập đến thuộc tính duy nhất, không lĩnh vực, như

  • GetModelProperties,
  • GetFilteredModelProperties,
  • GetPropertyValue,
  • OnXYZValidating,
  • OnXYZValidated,
  • OnXYZUpdating,
  • OnXYZUpdated,
  • GetXYZValue,

nơi XYZ là viết tắt của một trong hai Model, hoặc Property/ies, hoặc cả hai, và vân vân.

Như bạn có thể thấy không có Fields được đề cập với những tên này. Như Darin giải thích không có thay đổi trực tiếp nào về trạng thái của Mô hình được dung sai bởi Binder. Do đó không có Field trong các phương pháp của nó.

Và cũng có thể, bạn có thể muốn xem một lớp quan trọng khác: ModelBindingContext. Một thể hiện của lớp này được chuyển đến BindModel, và sau đó đến BindSimpleModel,BindComplexModel, tùy thuộc vào loại mô hình (string, int, ... được coi là đơn giản, mọi thứ khác đều phức tạp).

Vì vậy, bối cảnh này có các thuộc tính sau:

  • ModelXYZ, và
  • PropertyXYZ.

Nói cách khác bạn không có phương tiện để tham khảo các trường trong ViewModel của bạn trừ khi bạn không ghi đè các lớp này và thực hiện các hành động đặc biệt để làm như vậy.

Nhưng một lần nữa, hãy cẩn thận khi chiến đấu với khung làm việc, thay vào đó luôn dễ dàng theo dõi nó hơn.

EDIT: Lớp ModelMetadata giữ tất cả dữ liệu cần thiết để ràng buộc mô hình. Mã của nó tuy nhiên, cho thấy không có dấu hiệu của các lĩnh vực, tên trường, vv Chỉ có tài sản được tham chiếu và truy cập. Vì vậy, ngay cả khi bạn cố gắng kế thừa và ghi đè DefaultModelBinderModelBinderContext, bạn vẫn sẽ không thể truy cập vào các bộ lọc, không bao giờ biết công cụ sửa đổi truy cập của họ là gì: công khai, riêng tư, v.v.

Hy vọng điều này giải thích hầu hết.

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