How can I provide my own ICustomTypeDescriptor in ASP.NET MVC?

I am working on a small library for ASP.NET MVC 3 that should offer the best reuse of model metadata and easy matching from data entities from / to custom viewmodels. To do this, I need to provide my own implementation of ICustomTypeDescriptor for three different areas of interest in ASP.NET MVC:

  • Scaffolding
  • Check
  • Modelbinding

It seems like you can do this by installing System.Web.Mvc.ModelMetadataProviders.Current on my own CustomMetaDataProvider, but this is not enough to cover all three points above.

The problem is that there are several classes in System.Web.Mvc that call directly to this System.Web.TypeDescriptorHelper , which does not expand, because it looks like this:

 internal static class TypeDescriptorHelper { public static ICustomTypeDescriptor Get(Type type) { return new AssociatedMetadataTypeTypeDescriptionProvider(type).GetTypeDescriptor(type); } } 

The only solution I found is very inconvenient and requires subclassing the many types from System.Web.Mvc to make it work. I even had to fully implement CustomModelBinderDictionary just to rewrite one or two lines of code. This way it works, but it is a very dirty hack and will probably break the next time I upgrade to a new version of ASP.NET MVC.

So here is what I like to know . Did I skip any easy way to do this?

Bonus question . If not, and you are from the MVC team, can you consider creating an appropriate extension point in MVC 4; -)?

Edit: In response to the question why I need to encode my own TypeDescriptor: there are several reasons for this: 1. Most important: I need a workaround for the problem described in https://forums.asp.net/t/1614439.aspx/ 1 2. I also need to dynamically insert metadata for various reasons. For example, I want to encode my own Bind attribute, but BindAttribute is sealed. So instead of flowing out of it, I dynamically generate the corresponding BindAttribute from the TypeDescriptor when it detects my own implementation of the binding attribute.

+4
source share
2 answers

According to Brad Wilson (a member of the ASP.NET MVC team), this problem was put on the error list for MVC 4. So this seems like there is no good solution at the moment, but hopefully this will be resolved when MVC 4 comes out.

For anyone interested in my library for reuse metadata and metadata, as well as for matching models / views, feel free to subscribe to my blog at http://devermind.com , I am going to release the library there in a couple of weeks.

+1
source

I'm not sure what you are trying to do with custom implementations of Validation, ModelBinding and potentially ModelMetadata that cannot be executed using the DependencyResolver function in MVC?

New scaffolding support in the recent MVC 3 tool update can meet your scaffolding needs; however, I would like to look at the ability to connect to the DependencyResolver functions for ModelBinding, ModelMetadata, and Validation and see if they can achieve what you are looking for. I recently had a similar situation where I needed to implement many of these behaviors from scratch in order to provide a flexible structure, and I could only do this using the ModelMetadata and Validation providers using IoC. I also ended up inheriting DynamicObject (or ExpandoObject) on several occasions to provide even more flexibility. I know this is not a straightforward answer, but I'm not sure why you need access to anything lower than these extensibility points?

EDIT: If you want to reuse ModelMetadata for similar ViewModels to avoid overriding the same ModelMetadata in multiple places, you can consider the consequences of this. There are many times when you need certain data restrictions for your objects, but these restrictions should be in the DataModel and not in the ViewModel. A user may have slightly more restrictive rules. For example, you can indicate that certain fields are only accessible to the user in the ViewModel, but that the object used as the DataModel allows you to change the value (usually from your code). Similarly, you may encounter situations where the ModelMetadata used to create the Create view for the VideModel may be slightly different from the ViewModel used for the Edit view. Reusing them may seem like a great way to stay consistent and reduce code duplication, but it may be something you later regret. I recently ran into the same problem when I wanted to avoid writing a new ViewModel for every view that could cause a postback, I did not find the perfect solution that I like, but I think reusing ModelMetadata will cause more problems that it may decide in my opinion. Writing ViewModels for the views that need them will also likely eliminate your need for a custom BindAttribute implementation and forest issues. If I’m right in believing that I don’t want to create so many ViewModels with my own metadata, this is what makes you try to find implementations of custom BindAttribute, custom forests, custom ModelMetadata, custom validation and custom ModelBinding ... this may be worth looking at how long it will take to create ViewModels.

If you find a better approach, feel free to let me know :-)

0
source

All Articles