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
|
EndProject
|
||||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "XmlFormattersWebSite", "test\WebSites\XmlFormattersWebSite\XmlFormattersWebSite.kproj", "{C3123A70-41C4-4122-AD1C-D35DF8958DD7}"
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "XmlFormattersWebSite", "test\WebSites\XmlFormattersWebSite\XmlFormattersWebSite.kproj", "{C3123A70-41C4-4122-AD1C-D35DF8958DD7}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ValidationWebSite", "test\WebSites\ValidationWebSite\ValidationWebSite.kproj", "{87AB84B2-22C1-43C6-BB8A-1D327B446FB0}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
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|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.ActiveCfg = Release|Any CPU
|
||||||
{BDEEBE09-C0C4-433C-B0B8-8478C9776996}.Release|x86.Build.0 = 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.ActiveCfg = Debug|Any CPU
|
||||||
{0449D6D2-BE1B-4E29-8E1B-444420802C03}.Debug|Any CPU.Build.0 = 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
|
{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}
|
{BDEEBE09-C0C4-433C-B0B8-8478C9776996} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||||
{0449D6D2-BE1B-4E29-8E1B-444420802C03} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
|
{0449D6D2-BE1B-4E29-8E1B-444420802C03} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
|
||||||
{C3123A70-41C4-4122-AD1C-D35DF8958DD7} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
{C3123A70-41C4-4122-AD1C-D35DF8958DD7} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||||
|
{87AB84B2-22C1-43C6-BB8A-1D327B446FB0} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Builder;
|
using Microsoft.AspNet.Builder;
|
||||||
using Microsoft.AspNet.TestHost;
|
using Microsoft.AspNet.TestHost;
|
||||||
|
|
@ -14,60 +16,76 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||||
{
|
{
|
||||||
public class TryValidateModelTest
|
public class TryValidateModelTest
|
||||||
{
|
{
|
||||||
private readonly IServiceProvider _services = TestHelper.CreateServices(nameof(FormatterWebSite));
|
private readonly IServiceProvider _services = TestHelper.CreateServices(nameof(ValidationWebSite));
|
||||||
private readonly Action<IApplicationBuilder> _app = new FormatterWebSite.Startup().Configure;
|
private readonly Action<IApplicationBuilder> _app = new ValidationWebSite.Startup().Configure;
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task TryValidateModel_SimpleModelInvalidProperties()
|
public async Task TryValidateModel_ClearParameterValidationError_ReturnsErrorsForInvalidProperties()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var server = TestServer.Create(_services, _app);
|
var server = TestServer.Create(_services, _app);
|
||||||
var client = server.CreateClient();
|
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
|
// Act
|
||||||
var response = await client.GetAsync("http://localhost/TryValidateModel/GetInvalidUser");
|
var response = await client.PostAsync(url, content);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
var body = await response.Content.ReadAsStringAsync();
|
||||||
|
var json = JsonConvert.DeserializeObject<Dictionary<string, string>>(body);
|
||||||
var json = JsonConvert.DeserializeObject<Dictionary<string, string[]>>(
|
Assert.Equal(8, json.Count);
|
||||||
await response.Content.ReadAsStringAsync());
|
Assert.Equal("CompanyName cannot be null or empty.", json["product.CompanyName"]);
|
||||||
Assert.Equal("The field Id must be between 1 and 2000.", json["Id"][0]);
|
Assert.Equal("The field Price must be between 20 and 100.", json["product.Price"]);
|
||||||
Assert.Equal(
|
Assert.Equal("The Category field is required.", json["product.Category"]);
|
||||||
"The field Name must be a string or array type with a minimum length of '5'.", json["Name"][0]);
|
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]
|
[Fact]
|
||||||
public async Task TryValidateModel_DerivedModelInvalidType()
|
public async Task TryValidateModel_InvalidTypeOnDerivedModel_ReturnsErrors()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var server = TestServer.Create(_services, _app);
|
var server = TestServer.Create(_services, _app);
|
||||||
var client = server.CreateClient();
|
var client = server.CreateClient();
|
||||||
|
var url =
|
||||||
|
"http://localhost/ModelMetadataTypeValidation/TryValidateModelSoftwareViewModelWithPrefix";
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var response = await client.GetAsync("http://localhost/TryValidateModel/GetInvalidAdminWithPrefix");
|
var response = await client.GetAsync(url);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
var body = await response.Content.ReadAsStringAsync();
|
||||||
|
var json = JsonConvert.DeserializeObject<Dictionary<string, string>>(body);
|
||||||
var json = JsonConvert.DeserializeObject<Dictionary<string, string[]>>(
|
Assert.Equal(1, json.Count);
|
||||||
await response.Content.ReadAsStringAsync());
|
Assert.Equal("Product must be made in the USA if it is not named.", json["software"]);
|
||||||
Assert.Equal("AdminAccessCode property does not have the right value", json["admin"][0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task TryValidateModel_ValidDerivedModel()
|
public async Task TryValidateModel_ValidDerivedModel_ReturnsEmptyResponseBody()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var server = TestServer.Create(_services, _app);
|
var server = TestServer.Create(_services, _app);
|
||||||
var client = server.CreateClient();
|
var client = server.CreateClient();
|
||||||
|
var url =
|
||||||
|
"http://localhost/ModelMetadataTypeValidation/TryValidateModelValidModelNoPrefix";
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var response = await client.GetAsync("http://localhost/TryValidateModel/GetValidAdminWithPrefix");
|
var response = await client.GetAsync(url);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
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",
|
"TagHelperSample.Web": "1.0.0",
|
||||||
"TagHelpersWebSite": "1.0.0",
|
"TagHelpersWebSite": "1.0.0",
|
||||||
"UrlHelperWebSite": "1.0.0",
|
"UrlHelperWebSite": "1.0.0",
|
||||||
|
"ValidationWebSite": "1.0.0",
|
||||||
"ValueProvidersWebSite": "1.0.0",
|
"ValueProvidersWebSite": "1.0.0",
|
||||||
"VersioningWebSite": "1.0.0",
|
"VersioningWebSite": "1.0.0",
|
||||||
"ViewComponentWebSite": "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;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
namespace FormatterWebSite
|
namespace ValidationWebSite
|
||||||
{
|
{
|
||||||
public class AdminValidator : ValidationAttribute
|
public class CompanyNameAttribute : ValidationAttribute
|
||||||
{
|
{
|
||||||
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
|
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
|
||||||
{
|
{
|
||||||
var admin = (Administrator)value;
|
var valueString = value as string;
|
||||||
|
if (string.IsNullOrEmpty(valueString))
|
||||||
if (admin.AdminAccessCode != 1)
|
|
||||||
{
|
{
|
||||||
return new ValidationResult ("AdminAccessCode property does not have the right value");
|
return new ValidationResult("CompanyName cannot be null or empty.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
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