What does [Required] do? - c#

I found nothing on the web what [Required] actually does. The msdn-article is not explorative at all.
static class Program
{
public static Main()
{
var vustomer = new CustomerClass();
}
}
public class CustomerClass
{
public string m_FirstName;
[Required]
public string m_LastName;
}
As far as i understand, that should throw an exception since m_LastName is required, but not set. But i don't get one. I don't get what it's good for and what this actually does.

RequiredAttribute, like all other attributes, does nothing by itself other than annotate something (in this case, a field of a type). It is entirely up to the application that consumes the type to detect the presence of the attribute and respond accordingly.
Your sample program does not do this, so the attribute does not have any visible effect. Certain frameworks such as ASP.NET MVC and WPF do check for and respond to the presence of the attribute.

This attribute is used by the Validator class to add validation errors based on any types that inherit from ValidationAttribute. This is used by MVC model validation, for example.

In C#, attributes are almost decoration to classes and properties.
Except for a few security related attributes, most do nothing. They are used by a higher-level framework to do something.
In the case of ASP.NET 4 MVC, only when the object is part of a request that attribute is used to generate an error.
If you want to use that attribute in any other environment, you must write code to inspect it.
It won't do anything from a plain old public static void Main()

Documentation on RequiredAttribute:
Specifies that a data field value is required.
However this validation is typically only performed in the UI layer. It is not "baked" into the constructor or other low-level usage. If you want to manually fire the validation you could do something like:
var customer = new CustomerClass();
var context = new ValidationContext(customer, serviceProvider: null, items: null);
var results = new List<ValidationResult>();
var isValid = Validator.TryValidateObject(customer, context, results);
if (!isValid)
{
foreach (var validationResult in results)
{
Console.WriteLine(validationResult.ErrorMessage);
}
}

To add to the current answers, these are some of the practical uses I can think of out of my head:
Entity Framework use this to model the database as not nullable fields.
Javascript client side validation provides javascript libraries for checking if the input field has any data, else prevent the form submission avoiding unnecesary roundtrips to the server.
Server side validation (when doing model binding) also check when you are posting a model with that decorator that the attribute passed in is in the request. This determines if the model state should be set to an invalid state or not. (1)
There are also annotation for JSON.NET library that changes how the model is serialized/unserialized. I'm pretty confident (but not sure) that the Validate Schema of Json.net does take into consideration the 'Required' attribute when validating a schema.
Other attribute decorators are used on web services, but 'Required' is not one I know has it uses in this scenario.
Web api uses this attribute to mark the property as required on documentation help pages and model binding.
You can create your own application logic that can be aware of the 'Required' property. For example, on a view to mark the property with an * in the label if it's required.
This are some uses but you are not limited to them.
(1) Note: if your property is, for example, an int and you decorate it with Required, model state will never be on a invalid state. You should use Nullable properties for this use-cases.

Related

What is the correct way to handle controller request model validation with nullable reference types?

Say I have a request model object:
public class RequestModel
{
public string? Id { get; set; }
// other properties...
}
And I want to use that model for this example controller method:
public ResponseModel ExampleMethod(RequestModel request)
{
// FluentValidation validator
_validator.ValidateAndThrow(request);
// This method does not accept a nullable type
_dependency.DoSomething(request.Id); // Causes "Possible null reference argument for parameter" error
return new ResponseModel();
}
In this case it's correct for the Id property to be marked as nullable (because in theory the request could not include it). The validator will ensure that the properties are not null. However if I want to use this property in DoSomething() then I will get compiler warnings due to the fact that the Id could be null. The only solution I can find is to map the external request object to some internal version where the properties are not nullable.
However this would require the mapping to essentially be performing validation (by throwing some kind of exception during mapping if a null is encountered) which feels like a violation of separation of concerns:
public ResponseModel ExampleMethod(RequestModel request)
{
// FluentValidation validator
_validator.ValidateAndThrow(request);
// Map the request to an internal object - throw an exception if mapping fails due to null properties
var internalModel = _mapper.Map<InternalModel>(request);
// This method does not accept a nullable type
_dependency.DoSomething(internalModel.Id); // No more error
return new ResponseModel();
}
Not sure if I'm missing something here or if this is the only way to solve the problem. I can't make the property non-nullable as then it would require a default value (eg. empty string, or even worse - null! or default!) which would make it impossible to determine whether the property was missing in the request or was genuinely passed as an empty string. I believe something like this proposal may resolve the issue as then I would be able to indicate to the compiler that I'm expecting these non-nullable properties to be provided upon initialization (by model binding) rather than with a constructor. Am I missing some aspect of nullable reference types here that would make this any easier to deal with?
You have a model with an optional value. Within a user-defined method you validate that this value is defined. The compiler can't determine this behaviour and thous the warning.
To help the compiler you could use the null-forgiving operator like this:
_dependency.DoSomething(internalModel.Id!);
Instead of using allowing null and afterwards check this manually you should maybe use better the available model validation within ASP core. Within your model you should better mark your property with the RequiredAttribute and also manually calling a fluent validator is not needed if you register it within your startup code with .AddFluentValidation(). If your model and validator is correctly marked you can within your Controller method do something like this and you're done:
if(!ModelState.IsValid)
return BadRequest(ModelState);
The only solution I can find is to map the external request object to some internal version where the properties are not nullable.
This sounds like a great approach to me. It's very common to separate request models from your core business models. The role of a controller action (which this appears to be) is largely to coordinate the translation of outside requests to and from the core business logic.
You might even want to have your dependency use your internal model rather than the Id, to avoid primitive obsession. If your dependency "knows" that the number it's being given should represent the Id of a specific type of model, it may be less error-prone to make it impossible for someone to give it a number that has nothing to do with that model type (or an ID directly from an input model that they forgot to validate).
_dependency.DoSomething(internalModel);
However this would require the mapping to essentially be performing validation (by throwing some kind of exception during mapping if a null is encountered) which feels like a violation of separation of concerns
Validation of inputs is an implied part of any method's contract, including any method that returns a value. Does int.Parse() violate separation of concerns by throwing exceptions on bad inputs before returning an int?
If anything, you're violating separation of concerns by using a single model class to represent two different concepts (input versus domain model), which can change for different reasons.
There's only one "concern" involved with validating the input model and converting it into a known-valid domain model. That implies that you should probably separate that concern into its own method/class.
public ResponseModel ExampleMethod(RequestModel request)
{
var internalModel = _requestValidator.Validate(request);
_dependency.DoSomething(internalModel);
return new ResponseModel();
}
The fact that your _requestValidator is using fluent model validation and automapper is an implementation detail that this level of code (a controller action, e.g.) shouldn't have to worry about. Maybe you'll change that some day to use explicit hand-coded mapping. You'd want your unit tests to test that validation/mapping independent of this class's logic.

Required fields for Unit Testing in c#

I have an application form in my project and I want to write unit tests.
My code behind has required fields for server side validation to ensure the field is not blank. I need help to know if I've written this right because this is only my second day of writing unit test. please be nice i am only 13.
[Required(ErrorMessage = "Please provide a title")]
public string Title
{
get; set;
}
Then in my unit test I did
public void TitleIsNotBlank()
{
Assert.IsNotNullOrEmpty(_vm.Title);
}
Would this check that field is not blank?
It's important to understand that the [Required] attribute only decorates the property but it does NOT automatically validate it unless something calls upon its functionality.
By decorating the property, you are telling any other process that may inspect it that it should be required and what the error message should read. The MVC framework's validation, for instance, fires the validation within this attribute for you. That's when validation actually occurs.
In my opinion, this should ideally be tested at the business object level (when you actually assign the value of the model to an object and try to do something with it, like save it).
The assumption is that the attribute's validation code has been tested, so you don't need to. However, since your goal is to increase coverage, what you can do is test to make sure the field is "marked" as required by inspecting it and making sure it is decorated as such:
var type = typeof(YourModelClass);
var property = type.GetProperty("Title");
var attributes = (Required[])property.GetCustomAttributes(typeof(Required), false);
Assert.IsTrue(attributes.Length > 0);

How to add MetaData to a dynamically build MVC3 ViewModel?

One of the key features of a project I'm working on is the ability for the user to configure Forms (as in "Forms" to fill-up) based on a pool of pre-existing field types (well known types, for instance "user name", "date of birth" etc. but also "generic types" like "string", "DateTime" etc.).
We used to have a static ViewModel that worked fine for the "well known" types and looked like this:
public class UserInputModel
{
[StringLength(200)]
public string Name { get; set; }
[Required(ErrorMessageResourceName = "BirthDateEmptyError", ErrorMessageResourceType = typeof(Resources.ErrorMessages))]
public DateTime BirthDate { get; set; }
//Here comes a lot of other properties
}
All the known properties were listed and we were showing or hiding them given the context.
But the last requirement came and changed all that. The user shall now be able to add as many generic type fields as he wants. In order to do this, we decided to make this InputModel entirely dynamic. It now looks like this:
public class UserInputModel
{
// Each ModelProperty has an "Id" and a "Value" property
public ICollection<ModelProperty> Properties { get; set; }
}
This works like a charm. The razor view only has to iterates over the collection, create the corresponding controls for each property of the collection in a more than standard way:
#Html.TextBoxFor(m => m.Properties[index].Value);
... and we nicely get the data back as a filled form.
=> This works fine, but we don't have any client-side validation. For this, we would need some Metadata... which we don't have via annotations anymore since we're dynamically creating the model.
In order to provide those MetaData, I created a CustomModelMetadataProvider that inherits from DataAnnotationsModelMetadataProvider and registered it as the new ModelMetadataProvider in the Global.asax. The CreateMetadata() function gets called upon creation of the ViewModel, and that for each of the properties of my ViewModel... sofar so good.
Where the problem starts: in order to add some metadata to the current property, I first need to identify which property I am currently looking at ("Name" has a maxlength of 200, "date of birth" hasn't so I cannot assign a maxlength to every property per default). And somewhow I didn't manage to do that yet since all the properties have the same name Value and the same container type ModelProperty.
I tried accessing the container of the property via reflection, but since the ModelAccessor's target is the ViewModel itself (because of the lambda expression m => m.Properties), the following construct gives me the ViewModel as a whole, not just the ModelProperty:
var container = modelAccessor.Target.GetType().GetField("container");
var containerObject = (UserInputModel)container.GetValue(modelAccessor.Target);
I've been flipping this over and over but cannot find a way to identify which ModelProperty I have in hand. Is there a way to do this?
Update: after flipping this in every possible direction for a while, we finally went another way. We are basically using unobstrusive javascript to use MVC's validation capabilities without touching attributes nor metadata. In short, we add HTML attributes like value-data="true" (and all other required attributes) to the #Html.TextBoxFor() statements. This works wonderfully for all the atomic validations (required, stringlength etc.).
Tim, you can leverage what appears to be client-side validation through Ajax with the Remote attribute on your properties.
Basically, you'll need to set up a validation controller and then write some smarts into that controller. But at least you'd be able to write some helper methods and keep it all in one place. You would have a series of validators, based on the meta data that you are presenting to the end users, and each validator method would work for a particular type with good re-use.
The one pitfall to this approach would be that you would need to write a validation method for each type and condition that you want to support. Sounds like you're having to go down that road anyways, though.
Hope this helps.
See if this article help you: Technique for carrying metadata to View Models with AutoMapper.
Also use this one for ideas (custom model metadata provider): changing viewmodel's MetadataType attribute at runtime
Fluent validation is probably the best option for you in my mind, but its obviously up to you to select the best match among those above.
Update
Try use ModelMetadata and override ModelMetadataProvider: Dive Deep Into MVC: ModelMetadata and ModelMetadataProvider. This way you completely customize your model metadata (this replaces data annotations) and you have complete control on what is happening, rather than relying on ASP.NET MVC.
Another good place to look at it is Creating your own ModelMetadataProvider to handle custom attributes.
Hope this all is of help to you.

Validation in ASP.MVC 3.0

I have a model class :
public class YearlyChageRate
{
public int Year { get; set; }
public double Rate { get; set; }
}
and I want to check that Yeae is unique or no and in condition Year is not unique application show an error message to users.How can I check the Year filed is repeated or not?
Here is a good example:
http://tugberkugurlu.com/archive/asp-net-mvc-remote-validation-for-multiple-fields-with-additionalfields-property
And here too: MVC validation for unique
You can use Remote attribute in your model to perform check for unique value in database.
This is official example of Remote attribute: http://msdn.microsoft.com/en-us/library/gg508808(v=vs.98).aspx
And one more: http://www.a2zdotnet.com/View.aspx?Id=198
You could use the [Remote] validation attribute on your view model.
Although you can use DataAnnotations attributes for validation and the [Remote] attribute for checks against the DB, it's not a very good design choice.
Let me explain:
data access is a data-layer matter
validation is a business-layer matter
user input and feedback is a ui matter
With DataAnnotations, you're mixin 3 in 1. It can be faster, but surely not well designed.
You could try a more disciplinate approach, like this:
Have a method at business level that will take your object as a parameter, perform validation internally using a validation framework of your choiche;
This method will call the data access to persist the object only if the validation passed;
This method will always return to the UI the validated object, plus a collection of fields/errors if anything didn't validate;
When you read the output of the method in your ui, you can either display a success page if there were no errors, or redisplay the form with the validation errors returned. To do this, the use of the PRG pattern is highly recommended, as you should never display a page on a POST method. Google for the PRG pattern to learn more about it. MvcContrib has a nice ActionFilter called ModelStateToTempData to make the implementation of the PRG pattern something trivial.

Validating a class using DataAnnotations

I have a class that I am using to model my data in MVC. I have added some DataAnotations to mark fields that are required and I am using regular expressions to check valid Email Addresses. Everything works fine if the object is posted back to MVC and I have the ModelState property that I can check to confirm that the class is valid but how do I check to see if the class is valid outside of MVC using the same class and Data Anotations that I have already set up?
Here's a method that I've used in the past with Data Annotations to get all of the errors on an annotated object (it could use some improvements, but it's a good starting point:
public static IEnumerable<ErrorInfo> GetErrors(object instance)
{
return from prop in TypeDescriptor.GetProperties(instance).Cast<PropertyDescriptor>()
from attribute in prop.Attributes.OfType<ValidationAttribute>()
where !attribute.IsValid(prop.GetValue(instance))
select new ErrorInfo(prop.Name, attribute.FormatErrorMessage(String.Empty), instance);
}
There doesn't appear to be anything built into .NET 3.5. If you can develop against .NET 4, though, there is a Validator class that provides what you need:
Validator class on MSDN

Categories