<repo_name>managerger/FluentValidation<file_sep>/docs/_doc/mvc5/known-limitations.md
---
title: Known Limitations
---
MVC 5 performs validation in two passes. First it tries to convert the input values from the request into the types declared in your model, and then it performs model-level validation using FluentValidation. If you have non-nullable types in your model (such as `int` or `DateTime`) and there are no values submitted in the request, model-level validations will be skipped, and only the type conversion errors will be returned. 

This is a limitation of MVC 5's validation infrastructure, and there is no way to disable this behaviour. If you want all validation failures to be returned in one go, you must ensure that any value types are marked as nullable in your model (you can still enforce non-nullability with a `NotNull` or `NotEmpty` rule as necessary, but the underlying type must allow nulls). This only applies to MVC5 and WebApi 2. ASP.NET Core does not suffer from this issue as the validation infrastructure has been improved. 
<file_sep>/docs/_doc/aspnet/aspnet.md
---
title: Getting Started
---
FluentValidation provides built in support for ASP.NET Core, MVC5 and WebApi 2.

Note that support for MVC 5 and WebApi 2 is considered legacy and comes with several limitations. For an optimal experience, we recommend using FluentValidation with ASP.NET Core 2.1 or newer.

For details on using FluentValidation with MVC 5, [click here](/mvc5). For WebApi 2, [click here](/webapi). For ASP.NET Core, read on.<file_sep>/docs/_doc/mvc5.md
---
title: ASP.NET MVC 5 Integration
excerpt: Integration with ASP.NET MVC 5
date: 2019-3-22
icon: 
  name: icon_globe
color: green
sections:
  - /mvc5/getting-started
  - /mvc5/known-limitations
  - /mvc5/clientside-validation
  - /mvc5/manual-validation
  - /mvc5/validator-customisation
  - /mvc5/validator-interceptors
  - /mvc5/rulesets
  - /mvc5/ioc
---<file_sep>/src/FluentValidation/TestHelper/TestValidationResult.cs
#region License

// Copyright (c) <NAME> (http://www.jeremyskinner.co.uk)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// You may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// The latest version of this file can be found at http://github.com/JeremySkinner/FluentValidation

#endregion

namespace FluentValidation.TestHelper {
	using System;
	using System.Collections.Generic;
	using System.Linq;
	using System.Linq.Expressions;
	using System.Reflection;
	using System.Text.RegularExpressions;
	using Internal;
	using Results;

	// TODO: Remove the TValue generic and the IValidationResultTester interface from this for 9.0.
	public class TestValidationResult<T, TValue> : ValidationResult, IValidationResultTester where T : class {

		[Obsolete("Use properties on the parent class itself")]
		public ValidationResult Result { get; private set; }

		[Obsolete]
		public MemberAccessor<T, TValue> MemberAccessor { get; private set; }

		public TestValidationResult(ValidationResult validationResult, MemberAccessor<T, TValue> memberAccessor) : base(validationResult.Errors){
			Result = validationResult;
			MemberAccessor = memberAccessor;
			RuleSetsExecuted = validationResult.RuleSetsExecuted;
		}

		[Obsolete("Call ShouldHaveValidationError/ShouldNotHaveValidationError instead of Which.ShouldHaveValidationError/Which.ShouldNotHaveValidationError")]
		public ITestPropertyChain<TValue> Which {
			get {
				return new TestPropertyChain<TValue, TValue>(this, Enumerable.Empty<MemberInfo>());
			}
		}

		public IEnumerable<ValidationFailure> ShouldHaveValidationErrorFor<TProperty>(Expression<Func<T, TProperty>> memberAccessor) {
			string propertyName = ValidatorOptions.PropertyNameResolver(typeof(T), memberAccessor.GetMember(), memberAccessor);
			return ValidationTestExtension.ShouldHaveValidationError(Errors, propertyName, true);
		}

		public void ShouldNotHaveValidationErrorFor<TProperty>(Expression<Func<T, TProperty>> memberAccessor) {
			string propertyName = ValidatorOptions.PropertyNameResolver(typeof(T), memberAccessor.GetMember(), memberAccessor);
			ValidationTestExtension.ShouldNotHaveValidationError(Errors, propertyName, true);
		}

		public IEnumerable<ValidationFailure> ShouldHaveValidationErrorFor(string propertyName) {
			return ValidationTestExtension.ShouldHaveValidationError(Errors, propertyName, false);
		}

		public void ShouldNotHaveValidationErrorFor(string propertyName) {
			ValidationTestExtension.ShouldNotHaveValidationError(Errors, propertyName, false);
		}

		[Obsolete]
		IEnumerable<ValidationFailure> IValidationResultTester.ShouldHaveValidationError(IEnumerable<MemberInfo> properties) {
			var propertyName = properties.Any() ? GetPropertyName(properties) : ValidationTestExtension.MatchAnyFailure;
			return ValidationTestExtension.ShouldHaveValidationError(Errors, propertyName, true);
		}

		[Obsolete]
		void IValidationResultTester.ShouldNotHaveValidationError(IEnumerable<MemberInfo> properties) {
			var propertyName = properties.Any() ? GetPropertyName(properties) : ValidationTestExtension.MatchAnyFailure;
			ValidationTestExtension.ShouldNotHaveValidationError(Errors, propertyName, true);
		}

		[Obsolete]
		private string GetPropertyName(IEnumerable<MemberInfo> properties) {
			var propertiesList = properties.Where(x => x != null).Select(x => x.Name).ToList();

			if (MemberAccessor != null) {
				string memberName = ValidatorOptions.PropertyNameResolver(typeof(T), MemberAccessor.Member, MemberAccessor);

				if (!string.IsNullOrEmpty(memberName)) {
					propertiesList.Insert(0, memberName);
				}
			}

			return string.Join(".", propertiesList);
		}
	}

}
<file_sep>/docs/_doc/aspnet.md
---
title: ASP.NET Integration
excerpt: Integration with ASP.NET Core, ASP.NET MVC 5 and ASP.NET WebApi 2
date: 2018-12-1
icon: 
  name: icon_globe
color: green
sections:
  - /aspnet/aspnet
  - /aspnet/core
---<file_sep>/docs/_doc/mvc5/validator-interceptors.md
---
title: Validator Interceptors
---

You can further customize this process by using an interceptor. An interceptor has to implement the IValidatorInterceptor interface from the FluentValidation.Mvc namespace:

```csharp
public interface IValidatorInterceptor {
    ValidationContext BeforeMvcValidation(ControllerContext controllerContext, ValidationContext validationContext);
 
    ValidationResult AfterMvcValidation(ControllerContext controllerContext, ValidationContext validationContext, ValidationResult result);
}
```

This interface has two methods – BeforeMvcValidation and AfterMvcValidation. If you implement this interface in your validator classes then these methods will be called as appropriate during the MVC validation pipeline.

BeforeMvcValidation is invoked after the appropriate validator has been selected but before it is invoked. One of the arguments passed to this method is a ValidationContext that will eventually be passed to the validator. The context has several properties including a reference to the object being validated. If we want to change which rules are going to be invoked (for example, by using a custom ValidatorSelector) then we can create a new ValidationContext, set its Selector property, and return that from the BeforeMvcValidation method.

Likewise, AfterMvcValidation occurs after validation has occurs. This time, we also have a reference to the result of the validation. Here we can do some additional processing on the error messages before they’re added to modelstate.

As well as implementing this interface directly in a validator class, we can also implement it externally, and specify the interceptor by using a CustomizeValidatorAttribute on an action method parameter:

```csharp
public ActionResult Save([CustomizeValidator(Interceptor=typeof(MyCustomerInterceptor))] Customer cust) {
 //...
}
```

In this case, the interceptor has to be a class that implements IValidatorInterceptor and has a public, parameterless constructor. The advantage of this approach is that your validators don’t have to be in an assembly that directly references System.Web.Mvc.

Note that this is considered to be an advanced scenario. Most of the time you probably won’t need to use an interceptor, but the option is there if you want it.
<file_sep>/docs/_doc/mvc5/rulesets.md
---
title: Specifying a RuleSet for client-side messages
---

If you’re using rulesets alongside ASP.NET MVC, then you’ll notice that by default FluentValidation will only generate client-side error messages for rules not part of any ruleset. You can instead specify that FluentValidation should generate clientside rules from a particular ruleset by attributing your controller action with a RuleSetForClientSideMessagesAttribute:

```csharp
[RuleSetForClientSideMessages("MyRuleset")]
public ActionResult Index() {
   return View(new PersonViewModel());
}
```

You can also use the `SetRulesetForClientsideMessages` extension method within your controller action (you must have the FluentValidation.Mvc namespace imported):

```csharp
public ActionResult Index() {
   ControllerContext.SetRulesetForClientsideMessages("MyRuleset");
   return View(new PersonViewModel());
}
```
<file_sep>/docs/_doc/mvc5/manual-validation.md
---
title: Manual Validation
---

Sometimes you may want to manually validate an object in a MVC project. In this case, the validation results can be copied to MVC's modelstate dictionary:

```csharp
public ActionResult DoSomething() {
  var customer = new Customer();
  var validator = new CustomerValidator();
  var results = validator.Validate(customer);

  results.AddToModelState(ModelState, null);
  return View();
}
```

The AddToModelState method is implemented as an extension method, and requires a using statement for the FluentValidation namespace. Note that the second parameter is an optional model name, which will cause property names in the ModelState to be prefixed (eg a call to AddToModelState(ModelState, "Foo") will generate property names of "Foo.Id" and "Foo.Name" etc rather than just "Id" or "Name")

<file_sep>/docs/_doc/mvc5/getting-started.md
---
title: Getting Started
---

<div class="callout-block callout-info"><div class="icon-holder" markdown="1">*&nbsp;*{: .fa .fa-info-circle}
</div><div class="content" markdown="1">
{: .callout-title}
#### Deprecation Notice

Integration with ASP.NET MVC 5 is considered legacy and will not be supported beyond FluentValidation 8.x. 
For an optimal experience, we suggest using FluentValidtation with [ASP.NET Core](/aspnet).

</div></div>

FluentValidation can be configured to work with ASP.NET MVC 5 projects.

To enable MVC integration, you'll need to add a reference to the `FluentValidation.Mvc5` assembly from the appropriate NuGet package:

```shell
Install-Package FluentValidation.Mvc5
```

Once installed, you'll need to configure the `FluentValidationModelValidatorProvider` (which lives in the FluentValidation.Mvc namespace) during the `Application_Start` event of your MVC application, which is in your Global.asax. 

```csharp
protected void Application_Start() {
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);

    FluentValidationModelValidatorProvider.Configure();
}
```

Internally, FluentValidation's MVC integration makes use of a *validator factory* to know how to determine which validator should be used to validate a particular type. By default, FluentValidation ships with an AttributedValidatorFactory that allows you to link a validator to the type that it validates by decorating the class to validate with an attribute that identifies its corresponding validator:

```csharp
[Validator(typeof(PersonValidator))]
public class Person {
	public int Id { get; set; }
	public string Name { get; set; }
	public string Email { get; set; }
	public int Age { get; set; }
}
 
public class PersonValidator : AbstractValidator<Person> {
	public PersonValidator() {
		RuleFor(x => x.Id).NotNull();
		RuleFor(x => x.Name).Length(0, 10);
		RuleFor(x => x.Email).EmailAddress();
		RuleFor(x => x.Age).InclusiveBetween(18, 60);
	}
}
```

Instead of using an attribute, you can also use a custom validator factory with an IoC container. You can tell the `FluentValidationModelValidatorProvider` to use a different validator factory by passing a nested closure into the `Configure` method which allows the provider to be customized:

```csharp
FluentValidationModelValidatorProvider.Configure(provider => {
  provider.ValidatorFactory = new MyCustomValidatorFactory();
});
```

Finally, we can create the controller and associated view:

```csharp
public class PeopleController : Controller {
	public ActionResult Create() {
		return View();
	}
 
	[HttpPost]
	public ActionResult Create(Person person) {
 
		if(! ModelState.IsValid) { // re-render the view when validation failed.
			return View("Create", person);
		}
 
		TempData["notice"] = "Person successfully created";
		return RedirectToAction("Index");
 
	}
}
```

...and here's the corresponding view (using Razor):

```html
@Html.ValidationSummary()
 
@using (Html.BeginForm()) {
	Id: @Html.TextBoxFor(x => x.Id) @Html.ValidationMessageFor(x => x.Id)
	<br />
	Name: @Html.TextBoxFor(x => x.Name) @Html.ValidationMessageFor(x => x.Name) 		
	<br />
	Email: @Html.TextBoxFor(x => x.Email) @Html.ValidationMessageFor(x => x.Email)
	<br />
	Age: @Html.TextBoxFor(x => x.Age) @Html.ValidationMessageFor(x => x.Age)
 
	<br /><br />
 
	<input type="submit" value="submit" />
}
```

Now when you post the form MVC’s `DefaultModelBinder` will validate the Person object using the `FluentValidationModelValidatorProvider`.

*Note for advanced users* When validators are executed using this automatic integration, the [RootContextData](/start.html#root-context-data) contain an entry called `InvokedByMvc` with a value set to true, which can be used within custom validators to tell whether a validator was invoked automatically by MVC, or manually. 
<file_sep>/docs/_doc/webapi/manual-validation.md
---
title: Manual Validation
---
Sometimes you may want to manually validate an object in a WebApi project. In this case, the validation results can be copied to MVC's modelstate dictionary:

```csharp
public IHttpActionResult DoSomething() {
  var customer = new Customer();
  var validator = new CustomerValidator();
  var results = validator.Validate(customer);

  results.AddToModelState(ModelState, null);
  return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
```

The `AddToModelState` method is implemented as an extension method, and requires a using statement for the `FluentValidation.WebApi` namespace. Note that the second parameter is an optional model name, which will cause property names in the ModelState to be prefixed (eg a call to AddToModelState(ModelState, "Foo") will generate property names of "Foo.Id" and "Foo.Name" etc rather than just "Id" or "Name")
<file_sep>/docs/_doc/mvc5/validator-customisation.md
---
title: Validator Customisation
---

The downside of using this automatic integration is that you don’t have access to the validator directly which means that you don’t have as much control over the validation processes compared to running the validator manually.

You can use the CustomizeValidatorAttribute to configure how the validator will be run. For example, if you want the validator to only run for a particular ruleset then you can specify that ruleset name by attributing the parameter that is going to be validated:

```csharp
public ActionResult Save([CustomizeValidator(RuleSet="MyRuleset")] Customer cust) {
  // ...
}
```

This is the equivalent of specifying the ruleset if you were to pass a ruleset name to a validator:

```csharp
var validator = new CustomerValidator();
var customer = new Customer();
var result = validator.Validate(customer, ruleSet: "MyRuleset");
```

The attribute can also be used to invoke validation for individual properties:

```csharp
public ActionResult Save([CustomizeValidator(Properties="Surname,Forename")] Customer cust) {
  // ...
}
```
…which would be the equivalent of specifying properties in the call to validator.Validate:

```csharp
var validator = new CustomerValidator();
var customer = new Customer();
var result = validator.Validate(customer, properties: new[] { "Surname", "Forename" });
```

You can also use the CustomizeValidatorAttribute to skip validation for a particular type. This is useful for if you need to validate a type manually (for example, if you want to perform async validation then you'll need to instantiate the validator manually and call ValidateAsync as MVC's validation pipeline is not asynchronous).

```csharp
public ActionResult Save([CustomizeValidator(Skip=true)] Customer cust) {
  // ...
}
```
<file_sep>/docs/_doc/mvc5/ioc.md
---
title: Using an Inversion of Control Container
---

When using FluentValidation's ASP.NET MVC 5 integration you may wish to use an Inversion of Control container to instantiate your validators rather than relying on the attribute based approach. This can be achieved by writing a custom Validator Factory. 

The IValidatorFactory interface defines the contract for validator factories. 

```csharp
public interface IValidatorFactory {
  IValidator<T> GetValidator<T>();
  IValidator GetValidator(Type type);
}
```

Instead of implementing this interface directly, you can inherit from the `ValidatorFactoryBase` class which does most of the work for you. When you inherit from ValidatorFactoryBase you should override the `CreateInstance` method. In this method you should call in to your IoC container to resolve an instance of the specified type or return `null` if it does not exist (many containers have a "TryResolve" method that will do this automatically).

Once you've implemented this interface, you can set the `ValidatorFactory` of the provider during application startup:

```csharp
FluentValidationModelValidatorProvider.Configure(cfg => {
    cfg.ValidatorFactory = new MyValidatorFactory();
});
```<file_sep>/docs/_doc/webapi.md
---
title: ASP.NET WebApi 2 integration
excerpt: Integration with ASP.NET WebApi 2
date: 2019-3-22
icon: 
  name: icon_globe
color: green
sections:
  - /webapi/getting-started
  - /webapi/manual-validation
  - /webapi/validator-customization
  - /webapi/validator-interceptors
  - /webapi/ioc
---<file_sep>/docs/_doc/webapi/getting-started.md
---
title: Getting Started
---

<div class="callout-block callout-info"><div class="icon-holder" markdown="1">*&nbsp;*{: .fa .fa-info-circle}
</div><div class="content" markdown="1">
{: .callout-title}
#### Deprecation Notice

Integration with ASP.NET WebApi 2 is considered legacy and will not be supported beyond FluentValidation 8.x. 
For an optimal experience, we suggest using FluentValidtation with [ASP.NET Core](/aspnet).

</div></div>

FluentValidation can be configured to work with WebApi 2 projects. To enable WebApi integration, you'll need to add a reference to the `FluentValidation.WebApi` assembly from the appropriate NuGet package:

```shell
Install-Package FluentValidation.WebApi
```

Once installed, you'll need to configure the `FluentValidationModelValidatorProvider` (which lives in the `FluentValidation.WebApi` namespace) during your application's startup routine. This is usually inside the `Register` method of your `WebApiConfig` class which can be found in the App_Start directory. 

```csharp
public static class WebApiConfig {
    public static void Register(HttpConfiguration config) {
        config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }

        FluentValidationModelValidatorProvider.Configure(config);
    }
```

If you are self-hosting with OWIN, then this should instead be inside your OWIN startup class's `Configuration` method:

```csharp
public class Startup { 
    public void Configuration(IAppBuilder appBuilder) { 
        var config = new HttpConfiguration(); 

        config.Routes.MapHttpRoute( 
            name: "DefaultApi", 
            routeTemplate: "api/{controller}/{id}", 
            defaults: new { id = RouteParameter.Optional } 
        ); 

        FluentValidationModelValidatorProvider.Configure(config);


        appBuilder.UseWebApi(config); 
    } 
}
```

Internally, FluentValidation's WebApi integration makes use of a *validator factory* to determine which validator should be used to validate a particular type. By default, FluentValidation ships with an AttributedValidatorFactory that allows you to link a validator to the type that it validates by decorating the class to validate with an attribute that identifies its corresponding validator:

```csharp
[Validator(typeof(PersonValidator))]
public class Person {
	public int Id { get; set; }
	public string Name { get; set; }
	public string Email { get; set; }
	public int Age { get; set; }
}
 
public class PersonValidator : AbstractValidator<Person> {
	public PersonValidator() {
		RuleFor(x => x.Id).NotNull();
		RuleFor(x => x.Name).Length(0, 10);
		RuleFor(x => x.Email).EmailAddress();
		RuleFor(x => x.Age).InclusiveBetween(18, 60);
	}
}
```

Instead of using an attribute, you can also use a custom validator factory with an IoC container. You can tell the `FluentValidationModelValidatorProvider` to use a different validator factory by passing a nested closure into the `Configure` method which allows the provider to be customized:

```csharp
FluentValidationModelValidatorProvider.Configure(config, provider => {
  provider.ValidatorFactory = new MyCustomValidatorFactory();
});
```

Finally, we can create the controller:

```csharp
public class PeopleController : ApiController {
	[HttpPost]
	public IHttpActionResult Create(Person person) {
 
		if(! ModelState.IsValid) { // re-render the view when validation failed.
			return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
		}
 
		return new HttpResponseMessage(HttpStatusCode.OK);
	}
}
```

Now when you post data to the controller's `Create` method (for example, as JSON) then WebApi will automatically call into FluentValidation to find the corresponding validator. Any validation failures will be stored in the controller's `ModelState` dictionary which can be used to generate an error response which can be returned to the client. 

*Note for advanced users* When validators are executed using this automatic integration, the [RootContextData](/start.html#root-context-data) contain an entry called `InvokedByWebApi` with a value set to true, which can be used within custom validators to tell whether a validator was invoked automatically by WebApi, or manually. 
<file_sep>/docs/_doc/mvc5/clientside-validation.md
---
title: Clientside Validation
---

Note that FluentValidation will also work with ASP.NET MVC's client-side validation, but not all rules are supported. For example, any rules defined using a condition (with When/Unless), custom validators, or calls to Must will not run on the client side. The following validators are supported on the client:

* NotNull/NotEmpty
* Matches (regex)
* InclusiveBetween (range)
* CreditCard
* Email
* EqualTo (cross-property equality comparison)
* Length
