i Have a property CountryText that contain the text to show for the property country, So i need to do somehing like this:
[Display(Name=CountryText)]
public string Country { get; set; }
public string CountryText { get; set; }
How can I do it please??
UPDATE:
It's not possible to do it.
You would need a custom attribute to decorate your properties, and a custom model metada provider (usually inherited from DataAnnotationsModelMetadataProvider, which is the default in MVC apps). The custom provider would be neccessary to set the metadata defined in your custom attribute.
The problem is that you cannot access the model from the model metada provider. You can acces information on the types (model type, container type, attributes...) but not a concrete instance of the model, so you cannot get a property value and use it in the provider.
Alternative
You can however use a Html.Label to show the field title.
If you want to make it more "automatic" you can alwasy write a custom html helper which creates the label for you. This helper have full access to the model type and the model content, so you can still use a custom attribute, look for it on the html helper code, and use the content of the other property.
If it was possible with metadata provider
Your custom metadata provider should add all the neccesary metadata for the view model property. This metadata provider could be convention based or use custom attributes to add the additional info.
These blog entries explain perfecty how to implemente custom attribute and metadata provider.
Diving into ASP.NET MVC 3 Model Metadata Providers
Model Metadata and Validation Localization using Conventions
Related
I have a User class with multiple string properties, all of them required. The properties are used for different actions, like Create and Update.
In my form, on create action, i am using only a part of these properties, and, because of this, the ModelState is invalid.
Is there a way to specify to the ModelState that it should validate only the properties that are included in the POST data (inside the form) ? So the missing properties are ignored?
You can create different models for user creation and other actions with different sets of validation attributes.
Yea, you should create different view models for each specific action method ( if they have specific requirements ).
You can use the RequiredIf attribute from Foolproof to achieve this:
using Foolproof;
[RequiredIf("Tab", "Information")]
public bool UW_AgentCreditReportsAknowlegement { get; set; }
Just use one of the attributes and set the appropriate condition.
I have a Model Like this
public int Id {get;set;}
[Required]
public string FirstName{get; set}
[Required]
public string LastName{get; set}
The Id is auto generate in DB. when I want call Create action The ModelState says that "The Id field is required"!!!! I Found this for my problem but it not clean solution.
Is there an other way to solve this?
Is there a way that I change Mvc ModelBinder behavior for value types?
The best solution to this problem is to use a view model. A view model is a class that you specifically design to meet the requirements of your view. So your controller action will take this view model as parameter. Simply stop passing your domain models to your views. That's it.
And if you don't want to follow good practices and use view models you could disable this implicit validation by adding the following to your Application_Start:
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
another hack is to exclude this property from binding using the [Bind(Exclude = "Id")] attribute. Yeah, it's a hack but if you don't follow good practices you will have to live with hacks.
Although #DarinDimitrov suggested a good option to use View Models, In addition to that answer. Also, consider this option only when you don't want to create the View-Model
How about ModelState["Id"].Errors.Clear(); in your Post Action Method ?
You can also set the property type to Nullable<T>, and then just manually enforce any required validation you might need to do before working with the database.
public int? Id {get;set;}
Further Reading:
Unrequired property keeps getting data-val-required attribute
ASP.NET MVC optional field being treated as required
"The Id field is required" validation message on Create
I'm reading a book written by Julie Lerman on Code First. According to the book, annotations and fluent api give the same result. Everything depends on the style of the developer.
I know that annotations allow both to configure how code first generate database objects and how MVC customize UI elements. Let's say I use [Required, MaxLength(50)]. The attribute will generate a NOT NULL, nvarchar (50) in the database. It also will validate the input for that field.
[Required, MaxLength(50)]
public string Name { get; set; }
What if I decide to use Fluent API to configure Code first. Am I still going to need annotations to influence UI elements or using fluent API is going to be enough?
EDIT
How about annotations, such as Display that serve only for UI purposes? Do they have equivalents? If not, Will I need to use annotaions?
[Display(Name = "Date of Birth")]
public DateTime BirthDate { get; set; }
Thanks for helping
Data Annotation is the simplest way of telling a class to enforce some validation rule. You can do the same thing with Fluent API as well. Some people like doing it by data annotations and some people like it by doing with fluent API
Reasons to like it with Data Annotations
1) Keep the validation info about my entity in one place along with the entity definition
Reasons to like it with Fluent API
1) Keep my entity clean. It will have only my property info. No validation info. Clean and simple POCO. I will write validation on the OnModelCreating method in my data context class.
You can not do all Fluent API things with Data Annotations way. the same way you don't have few Data Annotations attributes equivalant not present with Fluent API way ( Ex : HasMinLength) . HasMinLength is something we will for our Model validation which usually makes sense in the UI.
For the UI Model Validation, you can not use the Fluent API alone. Fluent API's major role is to look into the fluent configuration we writes and act when creating the Model(Database) from the entities. Remember we are overriding the OnModelCreating method to write our fluent API configuration. So for the UI Validation (of my ViewModel), I would use the DataAnnotation way and use fluent API if i want to define some thing related to my datamodel like Define a foreign key or Map this Entity to a Table with different name etc..
EDIT : As per the question edit,
You should make use of the Data Annotations in this case. If you are doing code first. You may remember that that entity is going to be your Database table ( of course you can tell EF to ignore /rename specific columns). In that case, I would keep my Entities clean and Create a ViewModel which i will use in my UI. I will add my DataAnnotations in my ViewModel to handle it. I may write some mapping code which maps data from ViewModel to Model and Model to ViewModel wherever necessary.
If your entity model classes are doubling as your viewmodel classes, AND you are using the default out of the box DataAnnotationsValidationProvider, then you would need the dataannotations attributes on the model properties to get validation.
However, you should not double your entity classes as viewmodel classes. Take for instance, a controller that needs to have a ReturnUrl property in its model. You wouldn't want this in your entity model / database. Because of differences like this between the View model and the Entity model, the 2 should really be separate (yet cohesive) layers in your application. You can make them cohesive using a library like AutoMapper.
This is one of the reasons I prefer the fluent API. If you stick to the fluent API, then you would never put any attributes on any entity model classes or properties. When it comes time to show, insert, or update data, you put the attributes on the viewmodel classes only.
Also, the [Required] attribute on an entity type performs validation during SaveChanges, whereas a [Required] attribute on a viewmodel performs validation during model binding.
According to Julie Lerman's book on DbContext, you do NOT need any additional annotations to your Fluent API configuration. The Name property will get validated by Validation API as if it had been configured with Data Annotations.
According to the same book, MaxLength and Required are the only validation attributes with fluent API conterparts.
I swear to god, that I had seen something like (below) on one of the MSDN Article but I cant find this property attribute documentation anywhere.
public class MyViewModel{
[Required]
public bool Important {get;set;}
[ValidationDependsOn("Important")]
public bool HasVIPAccess {get;set;}
}
If you look at the above code (maybe a bad example), I am trying to establish a relationship between the two properties in such a way that validation of HasVIPAccess property depends on the validation of the property called Important.
the built in validation attribute that do something like that is [Compare("OtherProperty")] which means the property that you put this attribute on must equal OtherProperty
ex
public class MyViewModel{
[Required]
public bool Important {get;set;}
[Compare("Important")]
public bool HasVIPAccess {get;set;}
}
Note : Require MVC 3+
if you wanna other validation attributes you can check Mvc.ValidationTookit
if you want to understand the science behind it
this is new to mvc3 and you can implement your custom attribute like this fairly easy in mvc3
because IsValid now recives a ValidationContext parameter which contains information about the validation that is being performed like the type of the model and metadata associated with it so you can use reflection to get other properties and their value the CompareAttribute made use of this feature
FluentValidation.NET
You can do this by writing a custom validation attribute (this enables only server side validation)... Here is a relevant post Creating New Data Annotation Validation Attributes in MVC
However...if you want to get client side unobstrusive validation to work as well, then you need to do some javascript work...here is another post that talks about creating unobtrusive client side validation...Unobtrusive Client Validation with MVC 3
I'm trying to figure out how I can define validation rules for my domain objects in one single location within my application but have run in to a snag...
Some background: My application has several parts:
- Database
- DAL
- Business Logic Layer
- SOAP API Layer
- MVC website
The MVC website accesses the database via the SOAP API, just as third parties would. We are using server and and client side validation on the MVC website as well as in the SOAP API Layer.
To avoid having to manually write client side validation we are implementing strongly typed views in conjunction with the Html.TextBoxFor and Html.ValidationMessageFor HTML helpers, as shown in Step 3 here. We also create custom models for each form where one form takes input for multiple domain objects.
This is where the problem begins, the HTML helpers read from the model for the data annotation validation attributes. In most cases our forms deal with multiple domain objects and you can't specify more than one type in the <%#Page ... Inherits="System.Web.Mvc.ViewPage<MvcApplication.Models.SomeModel>" %> page directive. So we are forced to create a custom model class, which would mean duplicating validation attributes from the domain objects on to the model class.
I've spent quite some time looking for workarounds to this, such has referencing the same MetadataType from both the domain class and the custom MVC models, but that won't work for several reasons:
You can only specify one MetadataType attribute per class, so its a problem if a model references multiple domain objects, each with their own metadata type.
The data annotation validation code throws an exception if the model class doesn't contain a property that is specified in the referenced MetadataType which is a problem with the model only deals with a subset of the properties for a given domain object.
I've looked at other solutions as well but to no avail. If anyone has any ideas on how to achieve a single source for validation logic that would work across MVC client and server side validation functionality and other locations (such as my SOAP API) I would love to hear it!
Thanks in advance,
Matthew
What you should do is instead of trying to replicate the structure in the view models, use your existing models in the data model classes.
When you bind the form data back to the view model, you can restrict which columns will be bound back using the [Bind] attribute on the parameter. Or use any other approaches to do this.
So if your model creates classes like Product User and Category, and your view model needs to use some of their properties, create a view model like this:
public class PageViewModel
{
public Product Product { get; set; }
public Category Category { get; set; }
public User User { get; set; }
}
In your page you will be able to use them with
<%: Html.EditorFor(m => m.Product.ProductName) %>
In this case the validation attributes from your actual classes will be used, as required.
Does that give you an acceptable solution?
How about returning a container class that has nested types in your action method?
http://weblogs.asp.net/blogs/rajbk/image_63B7D5D4.png