From 1a62f104b445e5982625c81fc72f343d36d42345 Mon Sep 17 00:00:00 2001 From: Doug Bunting Date: Wed, 28 Jan 2015 09:59:40 -0800 Subject: [PATCH] Add functional test of `[Remote]` - #439 (3 of 3) - extended the Validation web site to include use of `[Remote]` - also confirm operation of the validation actions (which all reject their input) --- ...Site.Aria.RemoteAttribute_Home.Create.html | 95 ++++++++++++++++ ...Site.Root.RemoteAttribute_Home.Create.html | 95 ++++++++++++++++ .../RemoteAttributeValidationTest.cs | 103 ++++++++++++++++++ .../RemoteAttribute_VerifyController.cs | 25 +++++ .../RemoteAttribute_HomeController.cs | 41 +++++++ .../RemoteAttribute_VerifyController.cs | 18 +++ .../ValidationWebSite/Models/Person.cs | 36 ++++++ .../RemoteAttribute_HomeController.cs | 41 +++++++ .../RemoteAttribute_VerifyController.cs | 20 ++++ test/WebSites/ValidationWebSite/Startup.cs | 3 + .../Views/Shared/Create.cshtml | 75 +++++++++++++ .../Views/Shared/Details.cshtml | 76 +++++++++++++ .../Views/Shared/Error.cshtml | 7 ++ .../Views/Shared/_Layout.cshtml | 31 ++++++ .../Views/Shared/_ViewStart.cshtml | 3 + .../ValidationWebSite/wwwroot/readme.md | Bin 406 -> 730 bytes 16 files changed, 669 insertions(+) create mode 100644 test/Microsoft.AspNet.Mvc.FunctionalTests/Compiler/Resources/ValidationWebSite.Aria.RemoteAttribute_Home.Create.html create mode 100644 test/Microsoft.AspNet.Mvc.FunctionalTests/Compiler/Resources/ValidationWebSite.Root.RemoteAttribute_Home.Create.html create mode 100644 test/Microsoft.AspNet.Mvc.FunctionalTests/RemoteAttributeValidationTest.cs create mode 100644 test/WebSites/ValidationWebSite/AnotherArea/Controllers/RemoteAttribute_VerifyController.cs create mode 100644 test/WebSites/ValidationWebSite/Controllers/RemoteAttribute_HomeController.cs create mode 100644 test/WebSites/ValidationWebSite/Controllers/RemoteAttribute_VerifyController.cs create mode 100644 test/WebSites/ValidationWebSite/Models/Person.cs create mode 100644 test/WebSites/ValidationWebSite/MyArea/Controllers/RemoteAttribute_HomeController.cs create mode 100644 test/WebSites/ValidationWebSite/MyArea/Controllers/RemoteAttribute_VerifyController.cs create mode 100644 test/WebSites/ValidationWebSite/Views/Shared/Create.cshtml create mode 100644 test/WebSites/ValidationWebSite/Views/Shared/Details.cshtml create mode 100644 test/WebSites/ValidationWebSite/Views/Shared/Error.cshtml create mode 100644 test/WebSites/ValidationWebSite/Views/Shared/_Layout.cshtml create mode 100644 test/WebSites/ValidationWebSite/Views/Shared/_ViewStart.cshtml diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/Compiler/Resources/ValidationWebSite.Aria.RemoteAttribute_Home.Create.html b/test/Microsoft.AspNet.Mvc.FunctionalTests/Compiler/Resources/ValidationWebSite.Aria.RemoteAttribute_Home.Create.html new file mode 100644 index 0000000000..c7344ea519 --- /dev/null +++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/Compiler/Resources/ValidationWebSite.Aria.RemoteAttribute_Home.Create.html @@ -0,0 +1,95 @@ + + + + + + Create in Aria area. - My ASP.NET Application + + +
+
+
+ Validation web site +
+ +
+ +
+
+
+ +
+ + +

Create in Aria area.

+
+

Person

+
+ + +
+ +
+ + +
+
+ +
+ +
+ + +
+
+ +
+ +
+ + +
+
+ +
+ +
+ + +
+
+ +
+ +
+ + +
+
+ +
+
+ +
+
+
+
+
+ Go back to home +
+ + +
+ + + + + + + + + + \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/Compiler/Resources/ValidationWebSite.Root.RemoteAttribute_Home.Create.html b/test/Microsoft.AspNet.Mvc.FunctionalTests/Compiler/Resources/ValidationWebSite.Root.RemoteAttribute_Home.Create.html new file mode 100644 index 0000000000..3bb0b8666a --- /dev/null +++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/Compiler/Resources/ValidationWebSite.Root.RemoteAttribute_Home.Create.html @@ -0,0 +1,95 @@ + + + + + + Create in root area. - My ASP.NET Application + + +
+
+
+ Validation web site +
+ +
+ +
+
+
+ +
+ + +

Create in root area.

+
+

Person

+
+ + +
+ +
+ + +
+
+ +
+ +
+ + +
+
+ +
+ +
+ + +
+
+ +
+ +
+ + +
+
+ +
+ +
+ + +
+
+ +
+
+ +
+
+
+
+
+ Go back to home +
+ + +
+ + + + + + + + + + \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/RemoteAttributeValidationTest.cs b/test/Microsoft.AspNet.Mvc.FunctionalTests/RemoteAttributeValidationTest.cs new file mode 100644 index 0000000000..478f2beb85 --- /dev/null +++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/RemoteAttributeValidationTest.cs @@ -0,0 +1,103 @@ +// 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; +using System.Net.Http; +using System.Reflection; +using System.Threading.Tasks; +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.TestHost; +using Xunit; + +namespace Microsoft.AspNet.Mvc.FunctionalTests +{ + public class RemoteAttributeValidationTest + { + private static readonly Assembly _resourcesAssembly = + typeof(RemoteAttributeValidationTest).GetTypeInfo().Assembly; + private readonly IServiceProvider _provider = TestHelper.CreateServices(nameof(ValidationWebSite)); + private readonly Action _app = new ValidationWebSite.Startup().Configure; + + [Theory] + [InlineData("Aria", "/Aria")] + [InlineData("Root", "")] + public async Task RemoteAttribute_LeadsToExpectedValidationAttributes(string areaName, string pathSegment) + { + // Arrange + var server = TestServer.Create(_provider, _app); + var client = server.CreateClient(); + var expectedContent = await _resourcesAssembly.ReadResourceAsStringAsync( + "compiler/resources/ValidationWebSite." + areaName + ".RemoteAttribute_Home.Create.html"); + var url = "http://localhost" + pathSegment + "/RemoteAttribute_Home/Create"; + + // Act + var response = await client.GetAsync(url); + + // Assert + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.Equal("text/html", response.Content.Headers.ContentType.MediaType); + Assert.Equal("utf-8", response.Content.Headers.ContentType.CharSet); + var responseContent = await response.Content.ReadAsStringAsync(); + Assert.Equal(expectedContent, responseContent); + } + + [Theory] + [InlineData("", "\"/RemoteAttribute_Verify/IsIdAvailable rejects Joe1.\"")] + [InlineData("/Aria", "false")] + [InlineData("/AnotherAria", + "\"/AnotherAria/RemoteAttribute_Verify/IsIdAvailable rejects 'Joe4' with 'Joe1', 'Joe2', and 'Joe3'.\"")] + public async Task RemoteAttribute_VerificationAction_GetReturnsExpectedJson( + string pathSegment, + string expectedContent) + { + // Arrange + var server = TestServer.Create(_provider, _app); + var client = server.CreateClient(); + var url = "http://localhost" + pathSegment + + "/RemoteAttribute_Verify/IsIdAvailable?UserId1=Joe1&UserId2=Joe2&UserId3=Joe3&UserId4=Joe4"; + + // Act + var response = await client.GetAsync(url); + + // Assert + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.Equal("application/json", response.Content.Headers.ContentType.MediaType); + Assert.Equal("utf-8", response.Content.Headers.ContentType.CharSet); + var responseContent = await response.Content.ReadAsStringAsync(); + Assert.Equal(expectedContent, responseContent); + } + + [Theory] + [InlineData("", "\"/RemoteAttribute_Verify/IsIdAvailable rejects Jane1.\"")] + [InlineData("/Aria", "false")] + public async Task RemoteAttribute_VerificationAction_PostReturnsExpectedJson( + string pathSegment, + string expectedContent) + { + // Arrange + var server = TestServer.Create(_provider, _app); + var client = server.CreateClient(); + var url = "http://localhost" + pathSegment + "/RemoteAttribute_Verify/IsIdAvailable"; + var contentDictionary = new Dictionary + { + { "UserId1", "Jane1" }, + { "UserId2", "Jane2" }, + { "UserId3", "Jane3" }, + { "UserId4", "Jane4" }, + }; + var content = new FormUrlEncodedContent(contentDictionary); + + // Act + var response = await client.PostAsync(url, content); + + // Assert + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.Equal("application/json", response.Content.Headers.ContentType.MediaType); + Assert.Equal("utf-8", response.Content.Headers.ContentType.CharSet); + var responseContent = await response.Content.ReadAsStringAsync(); + Assert.Equal(expectedContent, responseContent); + } + } +} \ No newline at end of file diff --git a/test/WebSites/ValidationWebSite/AnotherArea/Controllers/RemoteAttribute_VerifyController.cs b/test/WebSites/ValidationWebSite/AnotherArea/Controllers/RemoteAttribute_VerifyController.cs new file mode 100644 index 0000000000..7273275381 --- /dev/null +++ b/test/WebSites/ValidationWebSite/AnotherArea/Controllers/RemoteAttribute_VerifyController.cs @@ -0,0 +1,25 @@ +// 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; +using ValidationWebSite.Models; + +namespace ValidationWebSite.AnotherArea.Controllers +{ + [Area("AnotherAria")] + [Route("[Area]/[Controller]/[Action]", Order = -2)] + public class RemoteAttribute_VerifyController : Controller + { + // Demonstrates validation action when AdditionalFields causes client to send multiple values. + [HttpGet] + public IActionResult IsIdAvailable(Person person) + { + return Json(data: string.Format( + "/AnotherAria/RemoteAttribute_Verify/IsIdAvailable rejects '{0}' with '{1}', '{2}', and '{3}'.", + person.UserId4, + person.UserId1, + person.UserId2, + person.UserId3)); + } + } +} \ No newline at end of file diff --git a/test/WebSites/ValidationWebSite/Controllers/RemoteAttribute_HomeController.cs b/test/WebSites/ValidationWebSite/Controllers/RemoteAttribute_HomeController.cs new file mode 100644 index 0000000000..0dc6221510 --- /dev/null +++ b/test/WebSites/ValidationWebSite/Controllers/RemoteAttribute_HomeController.cs @@ -0,0 +1,41 @@ +// 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; +using ValidationWebSite.Models; + +namespace ValidationWebSite.Controllers +{ + public class RemoteAttribute_HomeController : Controller + { + private static Person _person; + + [HttpGet] + [Route("[Controller]/[Action]")] + public IActionResult Create() + { + return View(); + } + + [HttpPost] + [Route("[Controller]/[Action]")] + public IActionResult Create(Person person) + { + ModelState.Remove("id"); + if (!ModelState.IsValid) + { + return View(person); + } + + _person = person; + return RedirectToAction(nameof(Details)); + } + + [Route("", Name = "Home", Order = -1)] + [Route("[Controller]/Index")] + public IActionResult Details() + { + return View(_person); + } + } +} \ No newline at end of file diff --git a/test/WebSites/ValidationWebSite/Controllers/RemoteAttribute_VerifyController.cs b/test/WebSites/ValidationWebSite/Controllers/RemoteAttribute_VerifyController.cs new file mode 100644 index 0000000000..2815414fb3 --- /dev/null +++ b/test/WebSites/ValidationWebSite/Controllers/RemoteAttribute_VerifyController.cs @@ -0,0 +1,18 @@ +// 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 ValidationWebSite.Controllers +{ + [Route("[Controller]/[Action]")] + public class RemoteAttribute_VerifyController : Controller + { + // This action is overloaded and may receive requests to validate either UserId1 or UserId2. + [AcceptVerbs("Get", "Post")] + public IActionResult IsIdAvailable(string userId1, string userId2) + { + return Json(data: string.Format("/RemoteAttribute_Verify/IsIdAvailable rejects {0}.", userId1 ?? userId2)); + } + } +} \ No newline at end of file diff --git a/test/WebSites/ValidationWebSite/Models/Person.cs b/test/WebSites/ValidationWebSite/Models/Person.cs new file mode 100644 index 0000000000..db2cf03df0 --- /dev/null +++ b/test/WebSites/ValidationWebSite/Models/Person.cs @@ -0,0 +1,36 @@ +// 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 ValidationWebSite.Models +{ + public class Person + { + public int Id { get; set; } + + // Controller in current area. + [Remote("IsIdAvailable", "RemoteAttribute_Verify")] + public string UserId1 { get; set; } + + // Controller in root area. + [Remote("IsIdAvailable", "RemoteAttribute_Verify", null, HttpMethod = "Post")] + public string UserId2 { get; set; } + + // Controller in MyArea area. + [Remote( + "IsIdAvailable", + "RemoteAttribute_Verify", + "Aria", + ErrorMessage = "/Aria/RemoteAttribute_Verify/IsIdAvailable rejects you.")] + public string UserId3 { get; set; } + + // Controller in AnotherArea area. + [Remote( + "IsIdAvailable", + "RemoteAttribute_Verify", + "AnotherAria", + AdditionalFields = "UserId1, UserId2, UserId3")] + public string UserId4 { get; set; } + } +} \ No newline at end of file diff --git a/test/WebSites/ValidationWebSite/MyArea/Controllers/RemoteAttribute_HomeController.cs b/test/WebSites/ValidationWebSite/MyArea/Controllers/RemoteAttribute_HomeController.cs new file mode 100644 index 0000000000..b42cf4c6be --- /dev/null +++ b/test/WebSites/ValidationWebSite/MyArea/Controllers/RemoteAttribute_HomeController.cs @@ -0,0 +1,41 @@ +// 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; +using ValidationWebSite.Models; + +namespace ValidationWebSite.MyArea.Controllers +{ + [Area("Aria")] + [Route("[Area]/[Controller]/[Action]", Order = -2)] + public class RemoteAttribute_HomeController : Controller + { + private static Person _person; + + [HttpGet] + public IActionResult Create() + { + return View(); + } + + [HttpPost] + public IActionResult Create(Person person) + { + ModelState.Remove("id"); + if (!ModelState.IsValid) + { + return View(person); + } + + _person = person; + return RedirectToAction(nameof(Details)); + } + + [Route("/[Area]", Name = "AriaHome", Order = -3)] + [Route("/[Area]/[Controller]/Index", Order = -2)] + public IActionResult Details() + { + return View(_person); + } + } +} \ No newline at end of file diff --git a/test/WebSites/ValidationWebSite/MyArea/Controllers/RemoteAttribute_VerifyController.cs b/test/WebSites/ValidationWebSite/MyArea/Controllers/RemoteAttribute_VerifyController.cs new file mode 100644 index 0000000000..ace49ede39 --- /dev/null +++ b/test/WebSites/ValidationWebSite/MyArea/Controllers/RemoteAttribute_VerifyController.cs @@ -0,0 +1,20 @@ +// 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 ValidationWebSite.MyArea.Controllers +{ + [Area("Aria")] + public class RemoteAttribute_VerifyController : Controller + { + // This action is overloaded and may receive requests to validate either UserId1 or UserId3. + // Demonstrates use of the default error message. + [AcceptVerbs("Get", "Post")] + [Route("[Area]/[Controller]/[Action]", Order = -2)] + public IActionResult IsIdAvailable(string userId1, string userId3) + { + return Json(data: false); + } + } +} \ No newline at end of file diff --git a/test/WebSites/ValidationWebSite/Startup.cs b/test/WebSites/ValidationWebSite/Startup.cs index 71cfda98e5..5c0d932f61 100644 --- a/test/WebSites/ValidationWebSite/Startup.cs +++ b/test/WebSites/ValidationWebSite/Startup.cs @@ -12,6 +12,9 @@ namespace ValidationWebSite { var configuration = app.GetTestConfiguration(); + // Set up file serving for JavaScript files. + app.UseFileServer(); + // Set up application services app.UseServices(services => { diff --git a/test/WebSites/ValidationWebSite/Views/Shared/Create.cshtml b/test/WebSites/ValidationWebSite/Views/Shared/Create.cshtml new file mode 100644 index 0000000000..eb0666c89f --- /dev/null +++ b/test/WebSites/ValidationWebSite/Views/Shared/Create.cshtml @@ -0,0 +1,75 @@ +@model ValidationWebSite.Models.Person +@{ + object areaObject; + ViewContext.ActionDescriptor.RouteValueDefaults.TryGetValue("area", out areaObject); + var areaName = (areaObject as string) ?? "root"; + + ViewBag.Title = "Create in " + areaName + " area."; +} + +

@ViewBag.Title

+@using (Html.BeginForm()) +{ +
+

Person

+
+ @Html.ValidationSummary(true, "", new { @class = "text-danger" }) + +
+ @Html.LabelFor(model => model.Id, htmlAttributes: new { @class = "control-label col-md-2" }) +
+ @Html.EditorFor(model => model.Id, new { htmlAttributes = new { @class = "form-control" } }) + @Html.ValidationMessageFor(model => model.Id, "", new { @class = "text-danger" }) +
+
+ +
+ @Html.LabelFor(model => model.UserId1, htmlAttributes: new { @class = "control-label col-md-2" }) +
+ @Html.EditorFor(model => model.UserId1, new { htmlAttributes = new { @class = "form-control" } }) + @Html.ValidationMessageFor(model => model.UserId1, "", new { @class = "text-danger" }) +
+
+ +
+ @Html.LabelFor(model => model.UserId2, htmlAttributes: new { @class = "control-label col-md-2" }) +
+ @Html.EditorFor(model => model.UserId2, new { htmlAttributes = new { @class = "form-control" } }) + @Html.ValidationMessageFor(model => model.UserId2, "", new { @class = "text-danger" }) +
+
+ +
+ @Html.LabelFor(model => model.UserId3, htmlAttributes: new { @class = "control-label col-md-2" }) +
+ @Html.EditorFor(model => model.UserId3, new { htmlAttributes = new { @class = "form-control" } }) + @Html.ValidationMessageFor(model => model.UserId3, "", new { @class = "text-danger" }) +
+
+ +
+ @Html.LabelFor(model => model.UserId4, htmlAttributes: new { @class = "control-label col-md-2" }) +
+ @Html.EditorFor(model => model.UserId4, new { htmlAttributes = new { @class = "form-control" } }) + @Html.ValidationMessageFor(model => model.UserId4, "", new { @class = "text-danger" }) +
+
+ +
+
+ +
+
+
+} + +
+ @Html.ActionLink("Go back to home", "Details") +
+ +@section Scripts { + @* Until script helpers are available, add script references manually. *@ + @* @Scripts.Render("~/bundles/jqueryval") *@ + + +} \ No newline at end of file diff --git a/test/WebSites/ValidationWebSite/Views/Shared/Details.cshtml b/test/WebSites/ValidationWebSite/Views/Shared/Details.cshtml new file mode 100644 index 0000000000..f86281b95c --- /dev/null +++ b/test/WebSites/ValidationWebSite/Views/Shared/Details.cshtml @@ -0,0 +1,76 @@ +@model ValidationWebSite.Models.Person +@{ + object areaObject; + ViewContext.ActionDescriptor.RouteValueDefaults.TryGetValue("area", out areaObject); + var areaName = (areaObject as string) ?? "root"; + + ViewBag.Title = "Details in " + areaName + " area."; +} + +

@ViewBag.Title

+
+

Person

+
+ +
+
+ @Html.DisplayNameFor(model => model.Id) +
+ +
+ @Html.DisplayFor(model => model.Id) +
+
+ +
+
+ @Html.DisplayNameFor(model => model.UserId1) +
+ +
+ @Html.DisplayFor(model => model.UserId1) +
+
+ +
+
+ @Html.DisplayNameFor(model => model.UserId2) +
+ +
+ @Html.DisplayFor(model => model.UserId2) +
+
+ +
+
+ @Html.DisplayNameFor(model => model.UserId3) +
+ +
+ @Html.DisplayFor(model => model.UserId3) +
+
+ +
+
+ @Html.DisplayNameFor(model => model.UserId4) +
+ +
+ @Html.DisplayFor(model => model.UserId4) +
+
+
+ +

+ @Html.ActionLink("Create a new one", "Create") | + @if (string.Equals("Aria", areaName, StringComparison.OrdinalIgnoreCase)) + { + @Html.RouteLink("Go back to home", "Home") + } + else + { + @Html.RouteLink("Go to Aria home", "AriaHome") + } +

\ No newline at end of file diff --git a/test/WebSites/ValidationWebSite/Views/Shared/Error.cshtml b/test/WebSites/ValidationWebSite/Views/Shared/Error.cshtml new file mode 100644 index 0000000000..5d73bf597b --- /dev/null +++ b/test/WebSites/ValidationWebSite/Views/Shared/Error.cshtml @@ -0,0 +1,7 @@ +@{ + Layout = "/Views/Shared/_Layout.cshtml"; + ViewBag.Title = "Error"; +} + +

Error.

+

An error occurred while processing your request.

\ No newline at end of file diff --git a/test/WebSites/ValidationWebSite/Views/Shared/_Layout.cshtml b/test/WebSites/ValidationWebSite/Views/Shared/_Layout.cshtml new file mode 100644 index 0000000000..d403cd1e79 --- /dev/null +++ b/test/WebSites/ValidationWebSite/Views/Shared/_Layout.cshtml @@ -0,0 +1,31 @@ + + + + + + @ViewBag.Title - My ASP.NET Application + + +
+
+
+ @Html.ActionLink("Validation web site", "Details", "RemoteAttribute_Home", routeValues: new { area = (object)null }) +
+ +
+
    +
  • @Html.ActionLink("Home", "Details", "RemoteAttribute_Home", routeValues: new { area = string.Empty })
  • +
  • @Html.ActionLink("Aria Home", "Details", "RemoteAttribute_Home", routeValues: new { area = "Aria" })
  • +
+
+
+
+ +
+ @RenderBody() +
+ + + @RenderSection("scripts", required: false) + + \ No newline at end of file diff --git a/test/WebSites/ValidationWebSite/Views/Shared/_ViewStart.cshtml b/test/WebSites/ValidationWebSite/Views/Shared/_ViewStart.cshtml new file mode 100644 index 0000000000..efda124b1f --- /dev/null +++ b/test/WebSites/ValidationWebSite/Views/Shared/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "~/Views/Shared/_Layout.cshtml"; +} \ No newline at end of file diff --git a/test/WebSites/ValidationWebSite/wwwroot/readme.md b/test/WebSites/ValidationWebSite/wwwroot/readme.md index 047eb18bae0915415c97b4908360a28e77f810c0..7317fcaa2484afb5779c7b0ad3d1f7fcb6321077 100644 GIT binary patch literal 730 zcma))!A`?45JcyU#6S28`Uf0(>;VY@f@=y1q#`6$k`nRrz?(Ip4P20wc?cjAFs$#DVj5lhJ3Y;0?=lS&q+gwXd z_V8=HzV&RWexRj(H!yOcQJ!8_l{@lCqUZ>)}!zttoVx_BAc>6N|!SyF|S delta 27 jcmcb`I*oZk!^9?~iOWt+u3}W+Qebdo2w?DJ&|?4qkkAMp