I want DefaultModelBinder not to perform any validation based on DataAnnotations metadata. I'm already using DataAnnotations with DynamicData for the admin area of my site, and I need a different set of validation rules for the MVC based front-end.
I'm decorating my classes with the MetadataType attribute. If I could have different MetadataType classes for the same model but used on different scenarios that would be great. If not I'm fine with just disabling the validation on the DefaultModelBinder, either by setting some property or by creating a specialized version of it.
Take a look at ModelValidatorProviders.Providers collection and leave only necessary entries.
ModelValidatorProviders.Providers.Clear() should propably solve your problem, but you should still look at it to see how it works.
Related
I am new to MVC, so please bear with me.
We have a large WebForms website, where content is managed by a
custom CMS. I have added DataAnnotation attributes to my model
properties. The attributes have an ErrorMessage property, but this
must be a compile-time constant.
I would like to get error message texts at runtime from out custom
CMS. We already do this in our WebForms pages, so the infrustructure
is in place i.e. manager classes with aproprate methods for retrieving
the correct texts by key.
My question is where do I hook in at runtime in order to populate the
texts from the CMS to be displayed when validation error occur
client-side or server-side?
One way I guess would be to create your own DataAnnotationsModelMetadataProvider. Derive from this class and override the CreateMetadata method. Don't forget to register your custom MetaDataProvider with the ModelMetadataProviders when your WebApp initializes.
Trying to craft a way for our designers to create custom asp.net webforms for our customers. The basic idea is that we have a general set of fields that can be saved, with each customer using a subset of those fields, each customer may have it's own names for similar concepts (ie one customer may use 'patient' and another 'customer'). Staying in customer context will help the designers build the correct form to meet the customers needs.
Now to do this I need to get as much as I can into the design experience as possible. I have a set of custom controls that derive from base controls like asp:TextBox and implements an interface to allows me to iterate over the controls and insert values from a data store, or fetch values to persist (Done). All of these controls need to be bound to a data point in my record object. I have a metadata system set up to allow the binding, but where I am running into trouble is in getting the list of available fields into a UITypeEditor. Namely, I haven't figured out how to (at design time) set the customer context on the form, and then access and use that value on each controls custom property editor (also at design time). Is this possible? Am I looking at this problem the wrong way? A form always has 1 and only one customer context. So in my forms project, each form will have a different customer id set to it.
As a second question how can I debug these editors? There is an expectation of web context in the editors, but there is no asp.net property grid. and even if there was, the editors are winforms components that wouldn't run in a browser.
I can include the code I currently have if it simplifies the problem, but even a simplified example is a half dozen classes.
I resolved these issues, posting here in case a general solution can be useful to anyone in the future.
I was able to get around this problem a bit by going the other way. My parent Page iterates over it's controls, and sets the CustomerId on all the controls that implement a specific interface.
As for debugging. Some refactoring got me to a place where I can easily swap out the webforms specific parts of my implementation for testing.
I have just noticed that DataTypeAttribute class is inherited from System.ComponentModel.DataAnnotations.ValidationAttribute.
In terms of ASP.NET MVC DefaultModelBinder class, is DataTypeAttribute is a validation attribute? In plain English, does ModelBinder validate the object according to DataTypeAttribute?
For example, if I specify DataType property to DataType.EmailAddress, will it validate the e-mail address or this attribute is only providing metadata for objects.
UPDATE
I found a similar question on SO :
Is the DataTypeAttribute validation working in MVC2?
So, according to that it is not working as a validation attribute. So, why it is inherited from System.ComponentModel.DataAnnotations.ValidationAttribute if it is not serving as a validation attribute?
DataTypeAttribute does not contain any validation logic itself.
The reason it derives from ValidationAttribute is so that you could create a new custom data type class, which was both a DataType and a Validation, all wrapped up into one. It's an unfortunate side-effect of .NET not allowing multiple inheritance.
So, yes, it's a validator... that does no validation by default. It's waiting patiently for you to do the heavy lifting. :)
Actually, if you look inside of MVC 3 Futures, you'll see that we leveraged this to create new custom validators where we knew that jQuery was already capable of providing client-side validation logic, and we added mirrored server-side validation logic (and preserved the DataType benefits for templating).
Based on the MVC3 source code the only purpose of the DataTypeAttribute is to populate the ModelMetadata.DataTypeName property .And this property is only used by the EditorFor/DisplayFor template generation. So you were right it has nothing to do with validation. So I don't know why is it inherited from ValidationAttribute. Maybe the framework authors reserved it for future use.
I seem to be having a lot of trouble with this.
I want to create an ASP.NET control that implements some core logic, and then I want to be able to derive several controls from that, which each implement their own specialized logic.
I started with a User Control, but I couldn't find a way to derive from it. I tried setting the Inherits attribute in the derived control but, no matter what I did, the derived control just didn't seem able to recognize the base control.
So then I tried a custom server side control by using a regular class that inherits from Control. (Note that all my rendering is done from code.) But I can't seem to find any way to get a page to recognize the control. I've tried different syntax in the #Register directive but either it tells me the src attribute is missing or it just can't find the control. (Note that I prefer not to create a separate assembly if I don't have to.) I have no idea what to put as the assembly if the control is from the current assembly.
Can anyone make suggestions on this? Any examples that would work for my configuration, or perhaps a different approach entirely?
Note that I am not currently using page/control code-behind. All my page scripting is stored in the same file as my markup.
In fact, despite various error messages about missing attributes in the #Register directive, I found it works just fine if I reduce the number of attributes in this directive to just tagprefix and namespace.
First post so please be gentle :)
When creating user controls in ASP.NET MVC, what is the best way to structure the code so that the controllers that invoke views that use the user controls do not all have to know so much about the controls? I would like to know a good way to maintain DRY while using user controls in ASP.NET MVC.
Please note, this question only pertain to user controls that require special handling and logic on a postback. I have no problem creating nice DRY code for user controls that are either view only (using RenderPartial) or that require some pre-processing to create the appropriate ViewModel (using RenderAction).
Also, this question pertains only to achieving reusable controls within an application. I am not worried about reusability between applications at this point.
To give a specific example, let's say I would like to create a 'Quick Add' user control which contains three entry fields, First Name, Last Name and Company Name and a submit button. When the QuickAdd functionality is used, the following steps should be performed independent of what page the control is on:
Validate that the fields were not empty, if they are, show an indicator.
Perform a lookup to a repository to see if the Company already exists, if not; create it.
Create a new contact associated to either the existing company or the newly created company
Re-render the existing page. If no validation errors, the user would see the exact same page again, otherwise the same page with validation errors.
My main problem with achieving DRY has to do with all the controllers that invoke views that contain the partial view end up having to have an Action Method to process the form submission from the Quick Add. Even if I break out the logic for processing the information into a separate controller and invoke that method from each of the other controllers it seems like a burden that each and every controller that invoke views that have reusable controls have to have that knowledge.
The other option I looked at was to have the reusable control always submit to a specific action method / controller but then there is no way for that controller to know how to re-populate the model appropriately for the specific controller that invoked the view that contained the reusable control (in step 4).
I am aware that there is talk of subcontrollers in MVC 2 (from this question ASP.NET MVC - Contained User Controls) but since it is not there yet, what is the best way to structure the code to achieve maximum reusability while maintaining DRY?
Is there an alternative to having to have all the controllers that invoke views that use a reusable control (with the characteristics of the one described above), having to have an Action Method to process the information from the control?
At the end of your post, you ask "Is there an alternative to having to have all the controllers... having to have an Action Method to process the information from the control"
The answer for that question is to write a custom model binder. Your custom model binder can be responsible for the populating the values from the incoming form control(s) into model or properties used by all of the controllers. Normally, you want to separate the validation from the model binding, but there is no reason that you couldn't combine them as well.
I highly recommend 6 Tips for ASP.NET MVC Model Binding for a deeper discussion of the topic along with some good references.
I'm not sure why you say the Quick Add form has to have an action method in each controller that uses it; if you wrap the Quick add functionality in a Html.BeginForm(); Html.EndForm() combo, you can have the beginform method specify the name of the action and controller, so you only need one controller.
I understand where you are coming from; it's something I have been thinking about to. While I don't know all the answers, I have some ideas for you to consider. Every controller action method is invoked via a ControllerActionInvoker class, which you can customize. This class handles invoking all of the action methods, so here you could embed certain aspects of reusable code across all or certain action methods.
Look into filters too, as there are a variety of filters that you can use or customize that fire for action methods that implement it. This way, code can run before and after the action method execution and result execution.
For validation, there is already validation components built in that will prevent page submission... you could also consider XVAL which has some other nice features. The Unity framework is an IOC container framework, which dynamic injection keeps things loosely coupled and DRY, as you can inject all kinds of references.
Also, you mentioned subcontrollers; the MVC preview has additional features you may be interested in... for instance, it has a RenderAction method that can render an action method within another action's view.
Hopefully that helps... so what am I missing?
Have a look at RenderAction and RenderPartial. Those are the canonical ways to arbitrarily inject a common control into a view.
Use RenderPartial when you want to include the data as part of your ViewData infrastructure.
Use RenderAction when you want the data to be separate from the ViewData infrastructure. The data will come from the controller method you specify in RenderAction.
Check out the NerdDinner tutorials, if you haven't done so already.