Added functionaltests for ModelMetadataType attribute and moved TryValidateModel tests actions to ValidationWebSite
This commit is contained in:
parent
08a578d01f
commit
cbed666cba
15
Mvc.sln
15
Mvc.sln
|
|
@ -126,6 +126,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.Common
|
|||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "XmlFormattersWebSite", "test\WebSites\XmlFormattersWebSite\XmlFormattersWebSite.kproj", "{C3123A70-41C4-4122-AD1C-D35DF8958DD7}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ValidationWebSite", "test\WebSites\ValidationWebSite\ValidationWebSite.kproj", "{87AB84B2-22C1-43C6-BB8A-1D327B446FB0}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -688,6 +690,18 @@ Global
|
|||
{BDEEBE09-C0C4-433C-B0B8-8478C9776996}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{BDEEBE09-C0C4-433C-B0B8-8478C9776996}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{BDEEBE09-C0C4-433C-B0B8-8478C9776996}.Release|x86.Build.0 = Release|Any CPU
|
||||
{87AB84B2-22C1-43C6-BB8A-1D327B446FB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{87AB84B2-22C1-43C6-BB8A-1D327B446FB0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{87AB84B2-22C1-43C6-BB8A-1D327B446FB0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{87AB84B2-22C1-43C6-BB8A-1D327B446FB0}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{87AB84B2-22C1-43C6-BB8A-1D327B446FB0}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{87AB84B2-22C1-43C6-BB8A-1D327B446FB0}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{87AB84B2-22C1-43C6-BB8A-1D327B446FB0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{87AB84B2-22C1-43C6-BB8A-1D327B446FB0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{87AB84B2-22C1-43C6-BB8A-1D327B446FB0}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{87AB84B2-22C1-43C6-BB8A-1D327B446FB0}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{87AB84B2-22C1-43C6-BB8A-1D327B446FB0}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{87AB84B2-22C1-43C6-BB8A-1D327B446FB0}.Release|x86.Build.0 = Release|Any CPU
|
||||
{0449D6D2-BE1B-4E29-8E1B-444420802C03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0449D6D2-BE1B-4E29-8E1B-444420802C03}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0449D6D2-BE1B-4E29-8E1B-444420802C03}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
|
|
@ -773,5 +787,6 @@ Global
|
|||
{BDEEBE09-C0C4-433C-B0B8-8478C9776996} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||
{0449D6D2-BE1B-4E29-8E1B-444420802C03} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
|
||||
{C3123A70-41C4-4122-AD1C-D35DF8958DD7} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||
{87AB84B2-22C1-43C6-BB8A-1D327B446FB0} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
|||
|
|
@ -0,0 +1,182 @@
|
|||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.TestHost;
|
||||
using Newtonsoft.Json;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||
{
|
||||
public class ModelMetadataAttributeTest
|
||||
{
|
||||
private readonly IServiceProvider _services = TestHelper.CreateServices(nameof(ValidationWebSite));
|
||||
private readonly Action<IApplicationBuilder> _app = new ValidationWebSite.Startup().Configure;
|
||||
|
||||
[Fact]
|
||||
public async Task ModelMetaDataTypeAttribute_ValidBaseClass_EmptyResponseBody()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_services, _app);
|
||||
var client = server.CreateClient();
|
||||
var input = "{ \"Name\": \"MVC\", \"Contact\":\"4258959019\", \"Category\":\"Technology\"," +
|
||||
"\"CompanyName\":\"Microsoft\", \"Country\":\"USA\",\"Price\": 21, \"ProductDetails\": {\"Detail1\": \"d1\"," +
|
||||
" \"Detail2\": \"d2\", \"Detail3\": \"d3\"}}";
|
||||
var content = new StringContent(input, Encoding.UTF8, "application/json");
|
||||
|
||||
var url = "http://localhost/ModelMetadataTypeValidation/ValidateProductViewModelIncludingMetadata";
|
||||
|
||||
// Act
|
||||
var response = await client.PostAsync(url, content);
|
||||
|
||||
// Assert
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal("{}", body);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ModelMetaDataTypeAttribute_InvalidPropertiesAndSubPropertiesOnBaseClass_ReturnsErrors()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_services, _app);
|
||||
var client = server.CreateClient();
|
||||
var input = "{ \"Price\": 2, \"ProductDetails\": {\"Detail1\": \"d1\"}}";
|
||||
var content = new StringContent(input, Encoding.UTF8, "application/json");
|
||||
|
||||
var url = "http://localhost/ModelMetadataTypeValidation/ValidateProductViewModelIncludingMetadata";
|
||||
|
||||
// Act
|
||||
var response = await client.PostAsync(url, content);
|
||||
|
||||
// Assert
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var json = JsonConvert.DeserializeObject<Dictionary<string, string>>(body);
|
||||
Assert.Equal(6, json.Count);
|
||||
Assert.Equal("CompanyName cannot be null or empty.", json["product.CompanyName"]);
|
||||
Assert.Equal("The field Price must be between 20 and 100.", json["product.Price"]);
|
||||
Assert.Equal("The Category field is required.", json["product.Category"]);
|
||||
Assert.Equal("The Contact Us field is required.", json["product.Contact"]);
|
||||
Assert.Equal("The Detail2 field is required.", json["product.ProductDetails.Detail2"]);
|
||||
Assert.Equal("The Detail3 field is required.", json["product.ProductDetails.Detail3"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ModelMetaDataTypeAttribute_InvalidComplexTypePropertyOnBaseClass_ReturnsErrors()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_services, _app);
|
||||
var client = server.CreateClient();
|
||||
var input = "{ \"Contact\":\"4255678765\", \"Category\":\"Technology\"," +
|
||||
"\"CompanyName\":\"Microsoft\", \"Country\":\"USA\",\"Price\": 21 }";
|
||||
var content = new StringContent(input, Encoding.UTF8, "application/json");
|
||||
|
||||
var url = "http://localhost/ModelMetadataTypeValidation/ValidateProductViewModelIncludingMetadata";
|
||||
|
||||
// Act
|
||||
var response = await client.PostAsync(url, content);
|
||||
|
||||
// Assert
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var json = JsonConvert.DeserializeObject<Dictionary<string, string>>(body);
|
||||
Assert.Equal(1, json.Count);
|
||||
Assert.Equal("The ProductDetails field is required.", json["product.ProductDetails"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ModelMetaDataTypeAttribute_InvalidClassAttributeOnBaseClass_ReturnsErrors()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_services, _app);
|
||||
var client = server.CreateClient();
|
||||
var input = "{ \"Contact\":\"4258959019\", \"Category\":\"Technology\"," +
|
||||
"\"CompanyName\":\"Microsoft\", \"Country\":\"UK\",\"Price\": 21, \"ProductDetails\": {\"Detail1\": \"d1\"," +
|
||||
" \"Detail2\": \"d2\", \"Detail3\": \"d3\"}}";
|
||||
|
||||
var content = new StringContent(input, Encoding.UTF8, "application/json");
|
||||
|
||||
var url = "http://localhost/ModelMetadataTypeValidation/ValidateProductViewModelIncludingMetadata";
|
||||
|
||||
// Act
|
||||
var response = await client.PostAsync(url, content);
|
||||
|
||||
// Assert
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var json = JsonConvert.DeserializeObject<Dictionary<string, string>>(body);
|
||||
Assert.Equal(1, json.Count);
|
||||
Assert.Equal("Product must be made in the USA if it is not named.", json["product"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ModelMetaDataTypeAttribute_ValidDerivedClass_EmptyResponseBody()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_services, _app);
|
||||
var client = server.CreateClient();
|
||||
var input = "{ \"Name\": \"MVC\", \"Contact\":\"4258959019\", \"Category\":\"Technology\"," +
|
||||
"\"CompanyName\":\"Microsoft\", \"Country\":\"USA\", \"Version\":\"2\"," +
|
||||
"\"DatePurchased\": \"/Date(1297246301973)/\", \"Price\" : \"110\" }";
|
||||
var content = new StringContent(input, Encoding.UTF8, "application/json");
|
||||
|
||||
var url = "http://localhost/ModelMetadataTypeValidation/ValidateSoftwareViewModelIncludingMetadata";
|
||||
|
||||
// Act
|
||||
var response = await client.PostAsync(url, content);
|
||||
|
||||
// Assert
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal("{}", body);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ModelMetaDataTypeAttribute_InvalidPropertiesOnDerivedClass_ReturnsErrors()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_services, _app);
|
||||
var client = server.CreateClient();
|
||||
var input = "{ \"Name\": \"MVC\", \"Contact\":\"425-895-9019\", \"Category\":\"Technology\"," +
|
||||
"\"CompanyName\":\"Microsoft\", \"Country\":\"USA\",\"Price\": 2}";
|
||||
var content = new StringContent(input, Encoding.UTF8, "application/json");
|
||||
|
||||
var url = "http://localhost/ModelMetadataTypeValidation/ValidateSoftwareViewModelIncludingMetadata";
|
||||
|
||||
// Act
|
||||
var response = await client.PostAsync(url, content);
|
||||
|
||||
// Assert
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var json = JsonConvert.DeserializeObject<Dictionary<string, string>>(body);
|
||||
Assert.Equal(2, json.Count);
|
||||
Assert.Equal("The field Price must be between 100 and 200.", json["software.Price"]);
|
||||
Assert.Equal("The field Contact must be a string with a maximum length of 10.", json["software.Contact"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ModelMetaDataTypeAttribute_InvalidClassAttributeOnBaseClassProduct_ReturnsErrors()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_services, _app);
|
||||
var client = server.CreateClient();
|
||||
var input = "{ \"Contact\":\"4258959019\", \"Category\":\"Technology\"," +
|
||||
"\"CompanyName\":\"Microsoft\", \"Country\":\"UK\",\"Version\":\"2\"," +
|
||||
"\"DatePurchased\": \"/Date(1297246301973)/\", \"Price\" : \"110\" }";
|
||||
var content = new StringContent(input, Encoding.UTF8, "application/json");
|
||||
|
||||
var url = "http://localhost/ModelMetadataTypeValidation/ValidateSoftwareViewModelIncludingMetadata";
|
||||
|
||||
// Act
|
||||
var response = await client.PostAsync(url, content);
|
||||
|
||||
// Assert
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var json = JsonConvert.DeserializeObject<Dictionary<string, string>>(body);
|
||||
Assert.Equal(1, json.Count);
|
||||
Assert.Equal("Product must be made in the USA if it is not named.", json["software"]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,8 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.TestHost;
|
||||
|
|
@ -14,60 +16,76 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
{
|
||||
public class TryValidateModelTest
|
||||
{
|
||||
private readonly IServiceProvider _services = TestHelper.CreateServices(nameof(FormatterWebSite));
|
||||
private readonly Action<IApplicationBuilder> _app = new FormatterWebSite.Startup().Configure;
|
||||
private readonly IServiceProvider _services = TestHelper.CreateServices(nameof(ValidationWebSite));
|
||||
private readonly Action<IApplicationBuilder> _app = new ValidationWebSite.Startup().Configure;
|
||||
|
||||
[Fact]
|
||||
public async Task TryValidateModel_SimpleModelInvalidProperties()
|
||||
public async Task TryValidateModel_ClearParameterValidationError_ReturnsErrorsForInvalidProperties()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_services, _app);
|
||||
var client = server.CreateClient();
|
||||
var input = "{ \"Price\": 2, \"Contact\": \"acvrdzersaererererfdsfdsfdsfsdf\", "+
|
||||
"\"ProductDetails\": {\"Detail1\": \"d1\", \"Detail2\": \"d2\", \"Detail3\": \"d3\"}}";
|
||||
var content = new StringContent(input, Encoding.UTF8, "application/json");
|
||||
var url =
|
||||
"http://localhost/ModelMetadataTypeValidation/" +
|
||||
"TryValidateModelAfterClearingValidationErrorInParameter?theImpossibleString=test";
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/TryValidateModel/GetInvalidUser");
|
||||
var response = await client.PostAsync(url, content);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
||||
|
||||
var json = JsonConvert.DeserializeObject<Dictionary<string, string[]>>(
|
||||
await response.Content.ReadAsStringAsync());
|
||||
Assert.Equal("The field Id must be between 1 and 2000.", json["Id"][0]);
|
||||
Assert.Equal(
|
||||
"The field Name must be a string or array type with a minimum length of '5'.", json["Name"][0]);
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var json = JsonConvert.DeserializeObject<Dictionary<string, string>>(body);
|
||||
Assert.Equal(8, json.Count);
|
||||
Assert.Equal("CompanyName cannot be null or empty.", json["product.CompanyName"]);
|
||||
Assert.Equal("The field Price must be between 20 and 100.", json["product.Price"]);
|
||||
Assert.Equal("The Category field is required.", json["product.Category"]);
|
||||
Assert.Equal("The field Contact Us must be a string with a maximum length of 20."+
|
||||
"The field Contact Us must match the regular expression '^[0-9]*$'.", json["product.Contact"]);
|
||||
Assert.Equal("CompanyName cannot be null or empty.", json["CompanyName"]);
|
||||
Assert.Equal("The field Price must be between 20 and 100.", json["Price"]);
|
||||
Assert.Equal("The Category field is required.", json["Category"]);
|
||||
Assert.Equal("The field Contact Us must be a string with a maximum length of 20."+
|
||||
"The field Contact Us must match the regular expression '^[0-9]*$'.", json["Contact"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TryValidateModel_DerivedModelInvalidType()
|
||||
public async Task TryValidateModel_InvalidTypeOnDerivedModel_ReturnsErrors()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_services, _app);
|
||||
var client = server.CreateClient();
|
||||
var url =
|
||||
"http://localhost/ModelMetadataTypeValidation/TryValidateModelSoftwareViewModelWithPrefix";
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/TryValidateModel/GetInvalidAdminWithPrefix");
|
||||
var response = await client.GetAsync(url);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
||||
|
||||
var json = JsonConvert.DeserializeObject<Dictionary<string, string[]>>(
|
||||
await response.Content.ReadAsStringAsync());
|
||||
Assert.Equal("AdminAccessCode property does not have the right value", json["admin"][0]);
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var json = JsonConvert.DeserializeObject<Dictionary<string, string>>(body);
|
||||
Assert.Equal(1, json.Count);
|
||||
Assert.Equal("Product must be made in the USA if it is not named.", json["software"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TryValidateModel_ValidDerivedModel()
|
||||
public async Task TryValidateModel_ValidDerivedModel_ReturnsEmptyResponseBody()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_services, _app);
|
||||
var client = server.CreateClient();
|
||||
var url =
|
||||
"http://localhost/ModelMetadataTypeValidation/TryValidateModelValidModelNoPrefix";
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/TryValidateModel/GetValidAdminWithPrefix");
|
||||
var response = await client.GetAsync(url);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("Admin user created successfully", await response.Content.ReadAsStringAsync());
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal("{}", body);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -32,6 +32,7 @@
|
|||
"TagHelperSample.Web": "1.0.0",
|
||||
"TagHelpersWebSite": "1.0.0",
|
||||
"UrlHelperWebSite": "1.0.0",
|
||||
"ValidationWebSite": "1.0.0",
|
||||
"ValueProvidersWebSite": "1.0.0",
|
||||
"VersioningWebSite": "1.0.0",
|
||||
"ViewComponentWebSite": "1.0.0",
|
||||
|
|
|
|||
|
|
@ -1,64 +0,0 @@
|
|||
// 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 Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace FormatterWebSite
|
||||
{
|
||||
public class TryValidateModelController : Controller
|
||||
{
|
||||
[HttpGet]
|
||||
public IActionResult GetInvalidUser()
|
||||
{
|
||||
var user = new User
|
||||
{
|
||||
Id = 0,
|
||||
Name = "x"
|
||||
};
|
||||
|
||||
// If ModelState.InValid is false return BadRequestOjectResult; else return empty string.
|
||||
if (!TryValidateModel(user))
|
||||
{
|
||||
return new BadRequestObjectResult(ModelState);
|
||||
}
|
||||
|
||||
return Content(string.Empty);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult GetInvalidAdminWithPrefix()
|
||||
{
|
||||
var admin = new Administrator()
|
||||
{
|
||||
Id = 1,
|
||||
Name = "John Doe",
|
||||
Designation = "Administrator",
|
||||
AdminAccessCode = 0
|
||||
};
|
||||
if (!TryValidateModel(admin,"admin"))
|
||||
{
|
||||
return new BadRequestObjectResult(ModelState);
|
||||
}
|
||||
|
||||
return Content(string.Empty);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult GetValidAdminWithPrefix()
|
||||
{
|
||||
var admin = new Administrator()
|
||||
{
|
||||
Id = 1,
|
||||
Name = "John Doe",
|
||||
Designation = "Administrator",
|
||||
AdminAccessCode = 1
|
||||
};
|
||||
if (!TryValidateModel(admin, "admin"))
|
||||
{
|
||||
return new BadRequestObjectResult(ModelState);
|
||||
}
|
||||
|
||||
return Content("Admin user created successfully");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
// 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;
|
||||
|
||||
namespace FormatterWebSite
|
||||
{
|
||||
[AdminValidator]
|
||||
public class Administrator : User
|
||||
{
|
||||
public int AdminAccessCode { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -3,17 +3,16 @@
|
|||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace FormatterWebSite
|
||||
namespace ValidationWebSite
|
||||
{
|
||||
public class AdminValidator : ValidationAttribute
|
||||
public class CompanyNameAttribute : ValidationAttribute
|
||||
{
|
||||
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
|
||||
{
|
||||
var admin = (Administrator)value;
|
||||
|
||||
if (admin.AdminAccessCode != 1)
|
||||
var valueString = value as string;
|
||||
if (string.IsNullOrEmpty(valueString))
|
||||
{
|
||||
return new ValidationResult ("AdminAccessCode property does not have the right value");
|
||||
return new ValidationResult("CompanyName cannot be null or empty.");
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using ValidationWebSite.ViewModels;
|
||||
|
||||
namespace ValidationWebSite.Controllers
|
||||
{
|
||||
public class ModelMetadataTypeValidationController : Controller
|
||||
{
|
||||
[HttpPost]
|
||||
public object ValidateProductViewModelIncludingMetadata([FromBody] ProductViewModel product)
|
||||
{
|
||||
return CreateValidationDictionary();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public object ValidateSoftwareViewModelIncludingMetadata([FromBody] SoftwareViewModel software)
|
||||
{
|
||||
return CreateValidationDictionary();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public object TryValidateModelAfterClearingValidationErrorInParameter(
|
||||
[Required, MaxLength(3), StringLength(10, MinimumLength = 3)] string theImpossibleString,
|
||||
[FromBody] ProductViewModel product)
|
||||
{
|
||||
// Clear ModelState entry. TryValidateModel should not add entries except those found within the
|
||||
// passed model.
|
||||
ModelState["theImpossibleString"].Errors.Clear();
|
||||
|
||||
TryValidateModel(product);
|
||||
|
||||
return CreateValidationDictionary();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public object TryValidateModelSoftwareViewModelWithPrefix()
|
||||
{
|
||||
var softwareViewModel = new SoftwareViewModel
|
||||
{
|
||||
Category = "Technology",
|
||||
CompanyName = "Microsoft",
|
||||
Contact = "4258393231",
|
||||
Country = "UK",
|
||||
DatePurchased = new DateTime(2010, 10, 10),
|
||||
Price = 110,
|
||||
Version = "2"
|
||||
};
|
||||
|
||||
TryValidateModel(softwareViewModel, "software");
|
||||
|
||||
return CreateValidationDictionary();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public object TryValidateModelValidModelNoPrefix()
|
||||
{
|
||||
var softwareViewModel = new SoftwareViewModel
|
||||
{
|
||||
Category = "Technology",
|
||||
CompanyName = "Microsoft",
|
||||
Contact = "4258393231",
|
||||
Country = "USA",
|
||||
DatePurchased = new DateTime(2010, 10, 10),
|
||||
Name = "MVC",
|
||||
Price = 110,
|
||||
Version = "2"
|
||||
};
|
||||
|
||||
TryValidateModel(softwareViewModel);
|
||||
|
||||
return CreateValidationDictionary();
|
||||
}
|
||||
|
||||
private Dictionary<string, string> CreateValidationDictionary()
|
||||
{
|
||||
var result = new Dictionary<string, string>();
|
||||
foreach (var item in ModelState)
|
||||
{
|
||||
var errorMessage = string.Empty;
|
||||
foreach (var error in item.Value.Errors)
|
||||
{
|
||||
if (error != null)
|
||||
{
|
||||
errorMessage = errorMessage + error.ErrorMessage;
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(errorMessage))
|
||||
{
|
||||
result.Add(item.Key, errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// 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;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace ValidationWebSite.Models
|
||||
{
|
||||
[ProductValidator]
|
||||
public class Product
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
[StringLength(20)]
|
||||
[RegularExpression("^[0-9]*$")]
|
||||
[Display(Name = "Contact Us")]
|
||||
public string Contact { get; set; }
|
||||
|
||||
[Range(0, 100)]
|
||||
public virtual int Price { get; set; }
|
||||
|
||||
[CompanyName]
|
||||
public string CompanyName { get; set; }
|
||||
|
||||
public string Country { get; set; }
|
||||
|
||||
[Required]
|
||||
public ProductDetails ProductDetails { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
// 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.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace ValidationWebSite.Models
|
||||
{
|
||||
public class ProductDetails
|
||||
{
|
||||
[Required]
|
||||
public string Detail1 { get; set; }
|
||||
|
||||
[Required]
|
||||
public string Detail2 { get; set; }
|
||||
|
||||
[Required]
|
||||
public string Detail3 { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
// 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;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace ValidationWebSite.Models
|
||||
{
|
||||
public class Software : Product
|
||||
{
|
||||
public string Version { get; set; }
|
||||
|
||||
[Required]
|
||||
public DateTime DatePurchased { get; set; }
|
||||
|
||||
[Range(100, 200)]
|
||||
public override int Price { get; set; }
|
||||
|
||||
[StringLength(10)]
|
||||
public new string Contact { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
// 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.ComponentModel.DataAnnotations;
|
||||
using ValidationWebSite.ViewModels;
|
||||
|
||||
namespace ValidationWebSite
|
||||
{
|
||||
public class ProductValidatorAttribute : ValidationAttribute
|
||||
{
|
||||
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
|
||||
{
|
||||
var product = value as ProductViewModel;
|
||||
if (product != null)
|
||||
{
|
||||
if (!product.Country.Equals("USA") || string.IsNullOrEmpty(product.Name))
|
||||
{
|
||||
return new ValidationResult("Product must be made in the USA if it is not named.");
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
var software = value as SoftwareViewModel;
|
||||
if (software != null)
|
||||
{
|
||||
if (!software.Country.Equals("USA") || string.IsNullOrEmpty(software.Name))
|
||||
{
|
||||
return new ValidationResult("Product must be made in the USA if it is not named.");
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return new ValidationResult("Expected either ProductViewModel or SoftwareViewModel instance but got "
|
||||
+ value.GetType() + " instance");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
// 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 Microsoft.AspNet.Builder;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
|
||||
namespace ValidationWebSite
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
var configuration = app.GetTestConfiguration();
|
||||
|
||||
// Set up application services
|
||||
app.UseServices(services =>
|
||||
{
|
||||
// Add MVC services to the services container
|
||||
services.AddMvc(configuration);
|
||||
});
|
||||
|
||||
app.UseErrorReporter();
|
||||
|
||||
// Add MVC to the request pipeline
|
||||
app.UseMvc(routes =>
|
||||
{
|
||||
routes.MapRoute(
|
||||
name: "default",
|
||||
template: "{controller}/{action}/{id?}");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>87ab84b2-22c1-43c6-bb8a-1d327b446fb0</ProjectGuid>
|
||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<DevelopmentServerPort>49635</DevelopmentServerPort>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties project_1json__JSONSchema="http://www.asp.net/media/4878834/project.json" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
// 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;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using ValidationWebSite.Models;
|
||||
|
||||
namespace ValidationWebSite.ViewModels
|
||||
{
|
||||
[ModelMetadataType(typeof(Product))]
|
||||
public class ProductViewModel
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
[Required]
|
||||
public string Contact { get; set; }
|
||||
|
||||
[Range(20, 100)]
|
||||
public int Price { get; set; }
|
||||
|
||||
[RegularExpression("^[a-zA-Z]*$")]
|
||||
[Required]
|
||||
public string Category { get; set; }
|
||||
|
||||
public string CompanyName { get; set; }
|
||||
|
||||
public string Country { get; set; }
|
||||
|
||||
public ProductDetails ProductDetails { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// 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;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using ValidationWebSite.Models;
|
||||
|
||||
namespace ValidationWebSite.ViewModels
|
||||
{
|
||||
[ModelMetadataType(typeof(Software))]
|
||||
public class SoftwareViewModel
|
||||
{
|
||||
[RegularExpression("^[0-9]*$")]
|
||||
public string Version { get; set; }
|
||||
|
||||
public DateTime DatePurchased { get; set; }
|
||||
|
||||
public int Price { get; set; }
|
||||
|
||||
public string Contact { get; set; }
|
||||
|
||||
public string Country { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Category { get; set; }
|
||||
|
||||
public string CompanyName { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"commands": {
|
||||
"web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:5001",
|
||||
"kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:5000"
|
||||
},
|
||||
"dependencies": {
|
||||
"Kestrel": "1.0.0-*",
|
||||
"Microsoft.AspNet.Mvc": "6.0.0-*",
|
||||
"Microsoft.AspNet.Mvc.TestConfiguration": "1.0.0",
|
||||
"Microsoft.AspNet.Server.IIS": "1.0.0-*",
|
||||
"Microsoft.AspNet.Server.WebListener": "1.0.0-*",
|
||||
"Microsoft.AspNet.StaticFiles": "1.0.0-*"
|
||||
},
|
||||
"frameworks": {
|
||||
"aspnet50": { },
|
||||
"aspnetcore50": { }
|
||||
},
|
||||
"webroot": "wwwroot"
|
||||
}
|
||||
Binary file not shown.
Loading…
Reference in New Issue