Adding ApiController.Validate : Fixes #1286
This commit is contained in:
parent
22869b41c0
commit
5a83383179
|
|
@ -7,6 +7,7 @@ using Microsoft.AspNet.Http;
|
|||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Microsoft.AspNet.Mvc.WebApiCompatShim;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
|
||||
namespace System.Web.Http
|
||||
{
|
||||
|
|
@ -83,6 +84,40 @@ namespace System.Web.Http
|
|||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the given entity and adds the validation errors to the <see cref="ApiController.ModelState"/>
|
||||
/// under an empty prefix.
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">The type of the entity to be validated.</typeparam>
|
||||
/// <param name="entity">The entity being validated.</param>
|
||||
public void Validate<TEntity>(TEntity entity)
|
||||
{
|
||||
Validate(entity, keyPrefix: string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the given entity and adds the validation errors to the <see cref="ApiController.ModelState"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">The type of the entity to be validated.</typeparam>
|
||||
/// <param name="entity">The entity being validated.</param>
|
||||
/// <param name="keyPrefix">
|
||||
/// The key prefix under which the model state errors would be added in the
|
||||
/// <see cref="ApiController.ModelState"/>.
|
||||
/// </param>
|
||||
public void Validate<TEntity>(TEntity entity, string keyPrefix)
|
||||
{
|
||||
var validator = Context.RequestServices.GetService<IBodyModelValidator>();
|
||||
var metadataProvider = Context.RequestServices.GetService<IModelMetadataProvider>();
|
||||
var modelMetadata = metadataProvider.GetMetadataForType(() => entity, typeof(TEntity));
|
||||
var validatorProvider = Context.RequestServices.GetService<ICompositeModelValidatorProvider>();
|
||||
var modelValidationContext = new ModelValidationContext(metadataProvider,
|
||||
validatorProvider,
|
||||
ModelState,
|
||||
modelMetadata,
|
||||
containerMetadata: null);
|
||||
validator.Validate(modelValidationContext, keyPrefix);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,6 +81,53 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
Assert.Equal(expected, formatters);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_CanValidateCustomObjectWithPrefix_Fails()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act
|
||||
var response = await client.GetStringAsync(
|
||||
"http://localhost/api/Blog/BasicApi/ValidateObjectWithPrefixFails?prefix=prefix");
|
||||
|
||||
// Assert
|
||||
var json = JsonConvert.DeserializeObject<Dictionary<string, string>>(response);
|
||||
Assert.Equal(1, json.Count);
|
||||
Assert.Equal("The field ID must be between 0 and 100.", json["prefix.ID"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_CanValidateCustomObject_IsSuccessFul()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act
|
||||
var response = await client.GetStringAsync("http://localhost/api/Blog/BasicApi/ValidateObject_Passes");
|
||||
|
||||
// Assert
|
||||
Assert.Equal("true", response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_CanValidateCustomObject_Fails()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act
|
||||
var response = await client.GetStringAsync("http://localhost/api/Blog/BasicApi/ValidateObjectFails");
|
||||
|
||||
// Assert
|
||||
var json = JsonConvert.DeserializeObject<Dictionary<string, string>>(response);
|
||||
Assert.Equal(1, json.Count);
|
||||
Assert.Equal("The field ID must be between 0 and 100.", json["ID"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ApiController_RequestProperty()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Http;
|
||||
|
|
@ -45,5 +47,52 @@ namespace WebApiCompatShimWebSite
|
|||
{
|
||||
return OptionsAccessor.Options.Formatters.Select(f => f.GetType().FullName).ToArray();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public bool ValidateObject_Passes()
|
||||
{
|
||||
var entity = new TestEntity { ID = 42 };
|
||||
Validate(entity);
|
||||
return ModelState.IsValid;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public object ValidateObjectFails()
|
||||
{
|
||||
var entity = new TestEntity { ID = -1 };
|
||||
Validate(entity);
|
||||
return CreateValidationDictionary();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public object ValidateObjectWithPrefixFails(string prefix)
|
||||
{
|
||||
var entity = new TestEntity { ID = -1 };
|
||||
Validate(entity, prefix);
|
||||
return CreateValidationDictionary();
|
||||
}
|
||||
|
||||
private class TestEntity
|
||||
{
|
||||
[Range(0, 100)]
|
||||
public int ID { get; set; }
|
||||
}
|
||||
|
||||
private Dictionary<string, string> CreateValidationDictionary()
|
||||
{
|
||||
var result = new Dictionary<string, string>();
|
||||
foreach (var item in ModelState)
|
||||
{
|
||||
var error = item.Value.Errors.SingleOrDefault();
|
||||
if (error != null)
|
||||
{
|
||||
var value = error.Exception != null ? error.Exception.Message :
|
||||
error.ErrorMessage;
|
||||
result.Add(item.Key, value);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue