Doctrine: Validate Model Data using Annotations - validation

In doctrine, is there a way that I could validate model data using annotations? Like the bellow example in c#
public class ProductMD {
[StringLength(50),Required]
public object Name { get; set; }
[StringLength(15)]
public object Color { get; set; }
[Range(0, 9999)]
public object Weight { get; set; }
}
So when the property Name is empty then it will give you error.

Unfortunately, starting from Doctrine2 there is no validation component integrated into the ORM itself anymore.
If, for example, you're using Doctrine2 with Symfony2, you can take advantage of the validation framework component by using #Assert annotations in the Doctrine entities.
If you don't use any framework, or if the framework you use does not provide a validation component, you can always use Doctrine's lifecycle callbacks to provide custom validation in #PrePersist and #PreUpdate (for more information, take a look here). In this case, there's more manual work to be done but it still sounds like a reasonable solution.

Related

ASP.NET Core MVC - Bind model containing property that uses an interface

I have a model that contains an interface based property, which the concrete implementation being discoverable via another property of the model.
public class SubscriptionViewModel
{
public Guid Id { get; set; }
...
public SubscriptionTypeEnum SubscriptionType { get; set; } // <- Determines the concrete class
public ISubscriptionCriteria SubscriptionCriteria { get; set; } //<- Property based on interface class
...
}
When the interface based property is present the model in the controller comes through as null. If removed, everything binds as expected.
[HttpPost("api/[controller]/[action]")]
public async Task Post([FromBody]SubscriptionViewModel model)
{
...
}
This will be because the controller doesn't know which solid implementation to use for the interface.
Any ideas how I can solve this? It looks like this might be achievable using a custom IModelBinderProvider or BindingBehaviorAttribute?
I guess I could have a SuperSubscriptionCriteria implementation that contains all possible properties used by concrete implementations of ISubscriptionCriteria and then rely on AutoMapper to convert them to the real implementations. But this seems like a hack and would require on-going maintenance as new ISubscriptionCriteria implementations are added.

How to inject dependencies used for validation in .NET MVC3?

We have quite a few validation methods that need to access repositories / database to do their work. So far we have been using the service locator pattern (albeit sparingly) to accomplish this in custom ValidationAttributes:
public override bool IsValid(object value)
{
// use custom service locator in our app's infrastructure
var repos = DependencyInjector.Current.GetService<IXyzRepository>();
...
}
I know this is :( upon as an anti-pattern, and we would like to use a more correct approach. We use unity, and I read this post that says to use a build-up method. However the link in the accepted answer says that the documentation is outdated (retired content).
The solution does not need to use a validation attribute, I suppose it could use IValidatableObject, however the problem remains: how to inject the dependency into the model. Do we need a custom model binder to do this?
Another solution would be to perform the validation in the controller, where dependency injection is easy. To me this feels cluttered though. I would like the model to be validated by the time it gets to the action method.
Also we sometimes use [RemoteAttribute] to perform some of these validations on the client. Currently those methods construct a viewmodel and delegate validation to the model by using the static Validator.TryValidateObject method.
How have you accomplished validation that requires an injected dependency to do its work, without using the SL anti-pattern?
How have you accomplished validation that requires an injected
dependency to do its work, without using the SL anti-pattern?
I use FluentValidation.NET to perform validation in my applications. It allows me to inject dependencies into my validators. It has a really nice integration with ASP.NET MVC. It also supports automatic client side validation for the standard rules just the same way as data annotations using jquery unobtrusive validate:
NotNull/NotEmpty
Matches (regex)
InclusiveBetween (range)
CreditCard
Email
EqualTo (cross-property equality comparison)
Length
I have never used data annotations to perform validation. They are absolutely useless when you need to handle some more complex validation scenarios where you need to validate dependent properties and even use some service. I put complex in italics in the previous sentence because, I don't think that validating that one of the 2 properties is required is a really complex validation scenario and yet, just checkout the amount of infrastructure crap you have to write in order to implement it using data annotations. Looking at this code you no longer know what you are validating.
Inject your validation into your Model.
Validation Attributes can become awkward to work with when your validation stories become more complex. Yuck!
I like to use Entity Framework with Code First. I have full control of my model at that point. I also use FluentValidation like #Darin Dimitrov and I really like its ease of use and simple syntax.
Here’s how you put it together.
I assume you have assembly with your interfaces or contracts.
This will be the base interface for your models…
using System.ComponentModel;
using FluentValidation.Results;
public interface IAbstractBase : IDataErrorInfo
{
bool IsValid { get; }
ValidationResult SelfValidate();
}
and its counterpart in your business layer looks like this…
using System;
using System.Linq;
using FluentValidation.Results;
using Contracts;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
public abstract class AbstractBase : IAbstractBase
{
#region IDataErrorInfo
public abstract ValidationResult SelfValidate();
[NotMapped]
public bool IsValid
{
get
{
return SelfValidate().IsValid;
}
}
[NotMapped]
public string Error
{
get
{
var results = SelfValidate().Errors.Select(s => string.Format("● {0}{1}", s.ErrorMessage, Environment.NewLine)).ToArray();
return string.Join("", results);
}
}
[NotMapped]
public IList<ValidationFailure> Errors
{
get
{
var results = SelfValidate().Errors;
return results;
}
}
[NotMapped]
public string this[string columnName]
{
get
{
var validationResults = SelfValidate();
if (validationResults == null) return string.Empty;
var columnResults = validationResults.Errors.FirstOrDefault(x => string.Compare(x.PropertyName, columnName, true) == 0);
return columnResults != null ? columnResults.ErrorMessage : string.Empty;
}
}
#endregion
}
This is your base class for your models. Make sure you implement the abstract method in your models. It should look like this.
public class MyModel : AbstractBase, IMyModel
{
private AbstractValidator<IMyModelValidator> _myModelValidator;
public MyModel():this(new MyModelValidator()){};
public MyModel(AbstractValidator<IMyModelValidator> myModelValidator){
_myModelValidator = myModelValidator;
};
public int MyModelId { get; set; }
public string Name { get; set; }
public DateTime CreatedDate { get; set; }
public override ValidationResult SelfValidate()
{
return _myModelValidator.Validate(this);
}
}
Your validator class will look something like this.
public class MyModelValidator : AbstractValidator<IMyModelValidator>
{
private IMyModelProvider _myModelProvider;
public MyModelValidator(IMyModelProvider myModelProvider){ _myModelProvider = myModelProvider;};
private void SetRules()
{
RuleFor(x => x.Name).NotEmpty().WithMessage("Please specify a project name.");
RuleFor(x => x.Name.Length).LessThanOrEqualTo(100).WithMessage("The project name must be less than or equal to 100 characters.");
}
public override ValidationResult Validate(IMyModel instance)
{
SetRules();
return base.Validate(instance);
}
}
Pass your validation results from your Model to your view in your Controller using the following call in your controller.
TryValidateModel(your model here);
After you call this in your controller call your model.IsValid property.
Make sure you register everything and you should be good to go. I assume you can fill in the missing pieces.
The big picture looks like this:

mvc3 validation when using buddy classes

I am working on an mvc3 application and having some problems with getting validation to work as I want.
The application is using buddy classes for the models. (This is something I haven't used in the past and I am a little confused why they are used...anyway)
I want to add required fields to ensure data been submitted is correct. I have tried adding the required field to the buddy class.
When I submit the form no client-side validation takes place and the debugger steps into the entity frameworks generated code. Here is complains that the fields that contain null values are causing are invalid. If I step through all of those it finally gets to the controller where my if (ModelState.IsValid) is showing false.
I have client-side validation switched on.
Am I meant to be applying the data validation at the buddy class level or at the view model?
One other question is why use buddy classes? to me they seem to over complicate things.
Updated added an example of the buddy class
[MetadataType(typeof (CustomerMetaData))]
public partial class Customer
{
public string Priorty
{
get
{
var desc = (Priority) Priority;
return desc.ToString().Replace('_', ' ');
}
}
internal class CustomerMetaData
{
[Required]
[DisplayName("Priorty")]
public string Priorty { get; set; }
Buddy classes are metadata classes to put data annotation attributes when you are not in control of the original class i.e. can't edit it. Typical situation is when the class is generated by an ORM like Entity Framework.
//Can't edit this class
public partial class YourClass{
public string SomeField {get; set;}
}
//Add a partial class
[MetadataType(typeof(YourClassMetadata))]
public partial class YourClass{
}
//And a metadata class
public class YourClassMetadata
{
[Required(ErrorMessage = "Some Field is required")]
public string SomeField {get; set;}
}
are you sure that you have [MetadataType(typeof(YourClassMetadata))]?
More about buddy classes here and here
You would typically use a buddy class when it isn't possible to add meta data to an entity class such as when a model is automatically generated by an ORM tool. In this case any meta data you had applied would be lost.
Therefore, your original (automatically generated) class would be defined as a partial class:
public partial class Customer
{
public string Priority { get; set; }
}
And then you would generate your buddy classes to add the meta data.
[MetadataType(typeof(CustomerMetaData))]
public partial class Customer
{
}
internal class CustomerMetaData
{
[Required]
public string Priority { get; set; }
}
You would then pass the Customer class to the view where the Priority would be set.
In your case i'm not sure if you only have one partial class or two (as the other is not shown but please provide if there is). I'm interested to know how you obtain the priority information from the customer as i'm wondering if this is an issue with how you use ModelState.IsValid? The reason I ask is that no set accessor is declared on the Priority property so i'm wondering how this is set from the view in order to report that it is not valid?
You would also use a buddy class when it isn't possible to add meta data to an entity class such as when a model is automatically generated by an WCF Data Contract.

ASP.Net MVC 3 DataAnnotations validating List<T>

I have a ViewModel that has been deserialized from JSON which looks something like this:
public class UserThingsUpdateViewModel
{
public IList<Thing> Things { get; set; }
[Required]
public int UserId { get; set; }
public int Age { get; set; }
}
Thing is also a ViewModel which also has various DataAnnotaion ValidationAttribute attributes on the properties.
The problem is that Lists don't seem to get validated and even after a through search I cant seem to find any articles that tackle this. Most suggest that the ViewModel is wrong if it includes a list.
So, what is the best way to validate my list and add Model Errors to the Model State?
Prior to checking ModelState.IsValid, you could add code to step through and validate each Thing, as follows:
foreach (var thing in Things)
TryValidateModel(thing);
This will validate each item, and add any errors to ModelState.
You could write a custom validator attribute and decorate the list property with it? That would allow you to write custom logic to get the elements out of the list and validate them.

How do you use Castle Validator with Subsonic generated classes?

Castle Validator uses attributes to specify validation rules. How can you hook these up with Subsonic's generated classes (or any classes where you can't define the attributes on)? Is there a way to programatically specify validation rules without using the attribute method?
I think the best way to do that is using MetadataType.
It's a DataAnnotations that let's your class have like a pair or something like that. I don't know how to explain it better so, let's for the samples:
You first need to add this directive to your code:
using System.ComponentModel.DataAnnotations;
Them you should create the partial class of you generated class with an attribute specifying that this class has an MetadataType:
[MetadataType(typeof(UserMetadata))]
public partial class User
{
}
Then you create your metadata class with your castle validation:
public class UserMetadata
{
[ValidateNonEmpty]
[ValidateLength(6, 24)]
public string Username { get; set; }
[ValidateNonEmpty]
[ValidateLength(6, 100)]
[ValidateEmail]
public string Email { get; set; }
[ValidateNonEmpty]
[ValidateLength(6, 24)]
public string Password { get; set; }
}
There are a few ways to do this - attributes is the lowest friction option, but obviously doesn't deal well with generated code or validation of multiple properties better expressed in code.
Take a look at the following link for some indications on how to do this blog post: Castle Validator Enhancements
If you have a look at the castle source code these are some good starting points:
IValidationContributor interface
DefaultValidationPerformer class

Resources