DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
11 Monitoring and Observability Tools for 2023
Learn more
  1. DZone
  2. Coding
  3. Frameworks
  4. EF Code First/MVC NotNullAttribute

EF Code First/MVC NotNullAttribute

Anders Abel user avatar by
Anders Abel
·
May. 03, 12 · Interview
Like (0)
Save
Tweet
Share
5.15K Views

Join the DZone community and get the full member experience.

Join For Free

Unfortunately MVC3 doesn’t respect the [Required] attribute’s AllowEmptyStrings property. When using a class both as an MVC model and as an EF Code First entity this is a problem. What if I want to allow empty strings, but not null values in the database?

The problem lies in the client side validation performed by MVC3. If a property in the model is marked with [Required] the jquery required validator will be enabled. It requires a non-empty string. I would prefer MVC to not emit a required validation if AllowEmptyStrings is true. Unfortunately the MVC code doesn’t honor that flag, but there is a workaround. Create a small attribute derived from RequiredAttribute.

public sealed class NotNullAttribute : RequiredAttribute
{
    public NotNullAttribute()
    {
        AllowEmptyStrings = true;
    }
}

To make it work, another attribute has to be set on the property to prevent the model binder from converting an empty string to null.

[NotNull]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string SomeProperty { get; set; }

It is surprisingly simple, but works thanks to a difference in how EF Code First and MVC3 handles attributes.

EF Code First recognizes the code above as a RequiredAttribute and sets the column in the database to not null accordingly. That is te normal behavior when querying for attributes – check if the attribute is of a given class, or any class derived from it. What is a bit surprising is that the MVC3 client validation does something else.

To understand why we first have to catch up on client side handling of validation attributes. When writing a custom validation attribute, client side validation is handled by implementing the IClientValidatable interface. However, the built in attributes belong to the System.ComponentModel.DataAnnotations and are not aware of client validation in MVC. For the built in attributes, there is a bit of special handling in MVC3 to give them client validation. The relevant part of the code is in DataAnnotationsModelValidatorProvider.cs:

// Produce a validator for each validation attribute we find
foreach (ValidationAttribute attribute in attributes.OfType<ValidationAttribute>()) {
    DataAnnotationsModelValidationFactory factory;
    if (!AttributeFactories.TryGetValue(attribute.GetType(), out factory)) {
        factory = DefaultAttributeFactory;
    }
    results.Add(factory(metadata, context, attribute));
}

The code checks for all attributes derived from ValidationAttribute. It then looks up the type of the attribute in a dictionary, to get a factory instance. That lookup is done on the exact type, not checking derived types. I don’t know if this is intentional or not, but it provides an excellent extension point. If a RequiredAttribute is passed in, a special factory producing a client side required rule is returned. For our NotNullAttribute there is no match so a DefaultAttributeFactory is returned. It will eventually produce client validation rules for any attribute that implements IClientValidatable. The NotNullAttribute doesn’t, so no client rules are created.

In a future version of MVC I would prefer if the RequiredAttributeAdapter checked the AllowEmptyStrings property before emitting the client validation rule. Until then, the small NotNullAttribute provides a workaround.

Entity Framework Attribute (computing)

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Monolithic First
  • DevSecOps: The Future of Secure Software Development
  • [DZone Survey] Share Your Expertise and Take our 2023 Web, Mobile, and Low-Code Apps Survey
  • Accelerating Enterprise Software Delivery Through Automated Release Processes in Scaled Agile Framework (SAFe)

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: