GetMetadataForProperty()
được khai báo trên lớp ModelMetadataProvider
.
AssociatedMetadataProvider
có nguồn gốc từ ModelMetadataProvider
. CreateMetadata()
được khai báo trên AssociatedMetadataProvider
. Các DataAnnotationsMetadataProvider
được ghi đè trong liên kết bạn cung cấp có nguồn gốc từ AssociatedMetadataProvider
.
Khuôn khổ MVC thực hiện cuộc gọi tới phương thức 's GetMetadataForProperty()
.
Lý do trọng CreateMetadata()
đang làm việc cho bạn là vì thực hiện mặc định của AssociatedModelMetadataProvider
của GetMetadataForProperty()
làm cho một cuộc gọi đến CreateMetadata()
. Nó trông giống như thế này:
public override ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName)
{
if (containerType == null)
{
throw new ArgumentNullException("containerType");
}
if (string.IsNullOrEmpty(propertyName))
{
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "propertyName");
}
PropertyDescriptor propertyDescriptor = this.GetTypeDescriptor(containerType).GetProperties().Find(propertyName, true);
if (propertyDescriptor == null)
{
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, MvcResources.Common_PropertyNotFound, new object[] { containerType.FullName, propertyName }));
}
return this.GetMetadataForProperty(modelAccessor, containerType, propertyDescriptor);
}
protected virtual ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, PropertyDescriptor propertyDescriptor)
{
IEnumerable<Attribute> attributes = this.FilterAttributes(containerType, propertyDescriptor, propertyDescriptor.Attributes.Cast<Attribute>());
return this.CreateMetadata(attributes, containerType, modelAccessor, propertyDescriptor.PropertyType, propertyDescriptor.Name);
}
Nếu bạn đang subclassing AssociatedMetadataProvider
như bạn đang ở trong liên kết mà bạn cung cấp, sau đó điểm mở rộng ưa thích của bạn là phương pháp CreateMetadata
, vì AssociatedMetadataProvider.GetMetadataForProperty()
phương pháp trước -giảm giá hợp đồng của phương thức CreateMetadata()
của bạn. Bằng cách đó, bạn biết rằng nếu có lỗi trong phương thức CreateMetadata()
của bạn, bạn đã biết rằng nguồn của lỗi nằm trong phương thức của bạn chứ không phải trong các đối số đã được truyền cho nó.
Ngoài ra, đây là nguồn gốc của phương pháp FilterAttributes()
, trong trường hợp bạn đang tự hỏi:
protected virtual IEnumerable<Attribute> FilterAttributes(Type containerType, PropertyDescriptor propertyDescriptor, IEnumerable<Attribute> attributes)
{
if (!typeof(ViewPage).IsAssignableFrom(containerType) && !typeof(ViewUserControl).IsAssignableFrom(containerType))
{
return attributes;
}
return attributes.Where<Attribute>(delegate (Attribute a) {
return !(a is ReadOnlyAttribute);
});
}
Nice! Cảm ơn câu trả lời hoàn chỉnh. – CGK
Xin lỗi, tôi muốn trao tiền thưởng cho bạn, nhưng quên thực sự làm điều đó. Tôi sẽ thêm một antoher và chấp nhận nó vào ngày mai. Hội chợ là công bằng. – CGK
Cảm ơn - hãy đánh giá cao điều đó. – smartcaveman