Adding the functional tests for MvcTagHelpers (1)

This commit is contained in:
Youngjune Hong 2015-01-02 13:27:22 -08:00
parent 52a984c52d
commit f8cb519c2f
25 changed files with 1013 additions and 2 deletions

15
Mvc.sln
View File

@ -112,6 +112,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "CompositeViewEngineWebSite"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ValueProvidersWebSite", "test\WebSites\ValueProvidersWebSite\ValueProvidersWebSite.kproj", "{14F79E79-AE79-48FA-95DE-D794EF4EABB3}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "MvcTagHelpersWebSite", "test\WebSites\MvcTagHelpersWebSite\MvcTagHelpersWebSite.kproj", "{920F8A0E-6F7D-4BBE-84FF-840B89099BE6}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ActionResultsWebSite", "test\WebSites\ActionResultsWebSite\ActionResultsWebSite.kproj", "{0A6BB4C0-48D3-4E7F-952B-B8917345E075}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "LoggingWebSite", "test\WebSites\LoggingWebSite\LoggingWebSite.kproj", "{0AD78AB5-D67C-49BC-81B1-0C51BFA82B5E}"
@ -612,6 +614,18 @@ Global
{14F79E79-AE79-48FA-95DE-D794EF4EABB3}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{14F79E79-AE79-48FA-95DE-D794EF4EABB3}.Release|x86.ActiveCfg = Release|Any CPU
{14F79E79-AE79-48FA-95DE-D794EF4EABB3}.Release|x86.Build.0 = Release|Any CPU
{920F8A0E-6F7D-4BBE-84FF-840B89099BE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{920F8A0E-6F7D-4BBE-84FF-840B89099BE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{920F8A0E-6F7D-4BBE-84FF-840B89099BE6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{920F8A0E-6F7D-4BBE-84FF-840B89099BE6}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{920F8A0E-6F7D-4BBE-84FF-840B89099BE6}.Debug|x86.ActiveCfg = Debug|Any CPU
{920F8A0E-6F7D-4BBE-84FF-840B89099BE6}.Debug|x86.Build.0 = Debug|Any CPU
{920F8A0E-6F7D-4BBE-84FF-840B89099BE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{920F8A0E-6F7D-4BBE-84FF-840B89099BE6}.Release|Any CPU.Build.0 = Release|Any CPU
{920F8A0E-6F7D-4BBE-84FF-840B89099BE6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{920F8A0E-6F7D-4BBE-84FF-840B89099BE6}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{920F8A0E-6F7D-4BBE-84FF-840B89099BE6}.Release|x86.ActiveCfg = Release|Any CPU
{920F8A0E-6F7D-4BBE-84FF-840B89099BE6}.Release|x86.Build.0 = Release|Any CPU
{0A6BB4C0-48D3-4E7F-952B-B8917345E075}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0A6BB4C0-48D3-4E7F-952B-B8917345E075}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0A6BB4C0-48D3-4E7F-952B-B8917345E075}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@ -690,6 +704,7 @@ Global
{B18ADE62-35DE-4A06-8E1D-EDD6245F7F4D} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
{A853B2BA-4449-4908-A416-5A3C027FC22B} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
{14F79E79-AE79-48FA-95DE-D794EF4EABB3} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
{920F8A0E-6F7D-4BBE-84FF-840B89099BE6} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
{0A6BB4C0-48D3-4E7F-952B-B8917345E075} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
{0AD78AB5-D67C-49BC-81B1-0C51BFA82B5E} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
EndGlobalSection

View File

@ -25,8 +25,10 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
{
foreach (var input in form.Descendants("input"))
{
if (input.Attributes("name").First().Value == "__RequestVerificationToken" &&
input.Attributes("type").First().Value == "hidden")
if (input.Attribute("name") != null &&
input.Attribute("type") != null &&
input.Attribute("name").Value == "__RequestVerificationToken" &&
input.Attribute("type").Value == "hidden")
{
return input.Attributes("value").First().Value;
}

View File

@ -0,0 +1,44 @@

<html>
<body>
<form action="/Customer/MvcTagHelper_Customer" method="post">
<div>
<label class="order" for="Number">Number</label>
<input class="form-control input-validation-error" type="number" data-val="true" data-val-range="The field Number must be between 1 and 100." data-val-range-max="100" data-val-range-min="1" id="Number" name="Number" value="" />
<span class="field-validation-error" data-valmsg-for="Number" data-valmsg-replace="true">A value is required.</span>
</div>
<div>
<label class="order" for="Name">Name</label>
<input type="text" id="Name" name="Name" value="" />
</div>
<div>
<label class="order" for="Email">Email</label>
<input type="email" id="Email" name="Email" value="" />
<span class="field-validation-valid" data-valmsg-for="Email" data-valmsg-replace="true"></span>
</div>
<div>
<label class="order" for="PhoneNumber">PhoneNumber</label>
<input type="tel" id="PhoneNumber" name="PhoneNumber" value="" />
</div>
<div>
<label class="order" for="Password">Password</label>
<input class="form-control input-validation-error" type="password" data-val="true" data-val-required="The Password field is required." id="Password" name="Password" />
<span class="field-validation-error" data-valmsg-for="Password" data-valmsg-replace="true">The Password field is required.</span>
</div>
<div>
<label class="order" for="Gender">Gender</label>
<input type="radio" Value="Male" id="Gender" name="Gender" /> Male
<input type="radio" Value="Female" id="Gender" name="Gender" /> Female
<span class="field-validation-valid" data-valmsg-for="Gender" data-valmsg-replace="true"></span>
</div>
<div class="order validation-summary-errors" data-valmsg-summary="true"><ul><li>A value is required.</li>
<li>The Password field is required.</li>
</ul></div>
<div class="order validation-summary-errors"><ul><li style="display:none"></li>
</ul></div>
<input type="submit"></input>
<input name="__RequestVerificationToken" type="hidden" value="{0}" /></form>
</body>
</html>

View File

@ -0,0 +1,42 @@

<html>
<body>
<form action="/Customer/MvcTagHelper_Customer" method="post">
<div>
<label class="order" for="Number">Number</label>
<input class="form-control" type="number" data-val="true" data-val-range="The field Number must be between 1 and 100." data-val-range-max="100" data-val-range-min="1" id="Number" name="Number" value="" />
<span class="field-validation-valid" data-valmsg-for="Number" data-valmsg-replace="true"></span>
</div>
<div>
<label class="order" for="Name">Name</label>
<input type="text" id="Name" name="Name" value="" />
</div>
<div>
<label class="order" for="Email">Email</label>
<input type="email" id="Email" name="Email" value="" />
<span class="field-validation-valid" data-valmsg-for="Email" data-valmsg-replace="true"></span>
</div>
<div>
<label class="order" for="PhoneNumber">PhoneNumber</label>
<input type="tel" id="PhoneNumber" name="PhoneNumber" value="" />
</div>
<div>
<label class="order" for="Password">Password</label>
<input class="form-control" type="password" data-val="true" data-val-required="The Password field is required." id="Password" name="Password" />
<span class="field-validation-valid" data-valmsg-for="Password" data-valmsg-replace="true"></span>
</div>
<div>
<label class="order" for="Gender">Gender</label>
<input type="radio" Value="Male" id="Gender" name="Gender" /> Male
<input type="radio" Value="Female" id="Gender" name="Gender" /> Female
<span class="field-validation-valid" data-valmsg-for="Gender" data-valmsg-replace="true"></span>
</div>
<div class="order validation-summary-valid" data-valmsg-summary="true"><ul><li style="display:none"></li>
</ul></div>
<div class="order"></div>
<input type="submit"></input>
<input name="__RequestVerificationToken" type="hidden" value="{0}" /></form>
</body>
</html>

View File

@ -0,0 +1,76 @@

<html>
<body>
<div>
<a href="">Product Index</a>
</div>
<div>
<a href="">Product List</a>
</div>
<div>
<a id="MvcTagHelperTestIndex" href="/">MvcTagHelperTest Index</a>
</div>
<div>
<a href="/">Default Controller</a>
</div>
<div>
<a href="">Product Index Fragment</a>
</div>
<div>
<a href="">Produt Submit Fragment</a>
</div>
<div>
<a id="MvcTagHelperTestIndexFragment" href="/#fragment">
MvcTagHelperTest Index Fragment
</a>
</div>
<div>
<a href="ftp://localhost/#fragment">
FTP MvcTagHelperTest Index Fragment
</a>
</div>
<div>
<a href="">
Unknown Protocol Product List
</a>
</div>
<div>
<a id="MvcTagHelperTestIndexProtocol" href="/">
Empty Protocol MvcTagHelperTest Index
</a>
</div>
<div>
<a href="">Customer Area Customer Index</a>
</div>
<div>
<a href="/Order/List">Href Order List</a>
</div>
<div>
<a href="">Non-existent Controller</a>
</div>
<div>
<a href="">
Non-existent Controller Fragment
</a>
</div>
<div>
<a href="">Non-existent Action</a>
</div>
<div>
<a id="Id" href="http://somewhere/">Some Where</a>
</div>
<div>
<a href="">
Unknown Protocol Non-existent Controller Fragment
</a>
</div>
<div>
<a href="">Product Route Non-existent Area Parameter</a>
</div>
<div>
<a href="">Non-existent Area</a>
</div>
</body>
</html>

View File

@ -0,0 +1,79 @@

<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<form action="/MvcTagHelper_Order/Submit" method="post">
<div>
<label class="order" for="Shipping">Shipping</label>
<input size="50" type="text" id="Shipping" name="Shipping" value="Your shipping method is UPSP" />
</div>
<div>
<label class="order" for="ShippingDateTime">ShippingDateTime</label>
<input type="datetime-local" id="ShippingDateTime" name="ShippingDateTime" value="1/1/0001 12:00:00 AM" />
</div>
<div>
<label class="order" for="Products">Products</label>
<select Multiple="multiple" id="Products" name="Products"><option value="7">Product_7</option>
<option value="8">Product_8</option>
<option selected="selected" value="9">Product_9</option>
<option value="10">Product_10</option>
<option value="11">Product_11</option>
<option value="12">Product_12</option>
</select>
</div>
<div>
<label class="order" for="OrderDate">OrderDate</label>
<input type="datetime" id="OrderDate" name="OrderDate" value="0001/01/01/ A.D." />
</div>
<div>
<label class="order" for="NeedSpecialHandle">NeedSpecialHandle</label>
<input checked="checked" id="NeedSpecialHandle" name="NeedSpecialHandle" type="checkbox" value="true" /><input name="NeedSpecialHandle" type="hidden" value="false" />
</div>
<div>
<label class="order" for="PaymentMethod">PaymentMethod</label>
<select id="PaymentMethod" multiple="multiple" name="PaymentMethod">
<option Value="Credit">Credit</option>
<option Value="Check" selected="selected">Check</option>
</select>
</div>
<div>
<label class="order" for="Customer_Number">Number</label>
<input class="form-control" type="number" data-val="true" data-val-range="The field Number must be between 1 and 100." data-val-range-max="100" data-val-range-min="1" id="Customer_Number" name="Customer.Number" value="1" />
<span class="field-validation-valid" data-valmsg-for="Customer.Number" data-valmsg-replace="true"></span>
</div>
<div>
<label class="order" for="Customer_Name">Name</label>
<input type="text" id="Customer_Name" name="Customer.Name" value="NameStringValue" />
</div>
<div>
<label class="order" for="Customer_Email">Email</label>
<input type="email" id="Customer_Email" name="Customer.Email" value="" />
<span class="field-validation-valid" data-valmsg-for="Customer.Email" data-valmsg-replace="true"></span>
</div>
<div>
<label class="order" for="Customer_PhoneNumber">PhoneNumber</label>
<input type="tel" id="Customer_PhoneNumber" name="Customer.PhoneNumber" value="" />
</div>
<div>
<label class="order" for="Customer_Password">Password</label>
<input class="form-control" type="password" data-val="true" data-val-required="The Password field is required." id="Customer_Password" name="Customer.Password" />
<span class="field-validation-valid" data-valmsg-for="Customer.Password" data-valmsg-replace="true"></span>
</div>
<div>
<label class="order" for="Customer_Gender">Gender</label>
<input type="radio" Value="Male" id="Customer_Gender" name="Customer.Gender" /> Male
<input type="radio" Value="Female" checked="checked" id="Customer_Gender" name="Customer.Gender" /> Female
<span class="field-validation-valid" data-valmsg-for="Customer.Gender" data-valmsg-replace="true"></span>
</div>
<div class="order validation-summary-valid" data-valmsg-summary="true"><ul><li style="display:none"></li>
</ul></div>
<input type="hidden" id="Customer_Key" name="Customer.Key" value="KeyA" />
<input type="submit"></input>
<input name="__RequestVerificationToken" type="hidden" value="{0}" /></form>
</body>
</html>

View File

@ -0,0 +1,23 @@

<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<form action="/MvcTagHelper_Home/ProductSubmit" method="get">
<div>
<label class="product" for="HomePage">HomePage</label>
<input size="50" type="url" id="HomePage" name="HomePage" value="http://www.contoso.com/" />
</div>
<div>
<label class="product" for="Description">Description</label>
<textarea rows="4" cols="50" class="product" id="Description" name="Description">
Type the product description</textarea>
</div>
<input type="submit"></input>
</form>
</body>
</html>

View File

@ -0,0 +1,92 @@
// 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.Net.Http.Headers;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.TestHost;
using MvcTagHelpersWebSite;
using Xunit;
namespace Microsoft.AspNet.Mvc.FunctionalTests
{
public class MvcTagHelpersTests
{
private readonly IServiceProvider _provider = TestHelper.CreateServices("MvcTagHelpersWebSite");
private readonly Action<IApplicationBuilder> _app = new Startup().Configure;
private static readonly Assembly _resourcesAssembly = typeof(TagHelpersTests).GetTypeInfo().Assembly;
[Theory]
[InlineData("Index", null)]
[InlineData("Order", "/MvcTagHelper_Order/Submit")]
[InlineData("Product", null)]
[InlineData("Customer", "/Customer/MvcTagHelper_Customer")]
public async Task MvcTagHelpers_GeneratesExpectedResults(string action, string antiForgeryPath)
{
// Arrange
var server = TestServer.Create(_provider, _app);
var client = server.CreateClient();
var expectedMediaType = MediaTypeHeaderValue.Parse("text/html; charset=utf-8");
// The K runtime compiles every file under compiler/resources as a resource at runtime with the same name
// as the file name, in order to update a baseline you just need to change the file in that folder.
var expectedContent =
await _resourcesAssembly.ReadResourceAsStringAsync
("compiler/resources/MvcTagHelpersWebSite.MvcTagHelper_Home." + action + ".html");
// Act
// The host is not important as everything runs in memory and tests are isolated from each other.
var response = await client.GetAsync("http://localhost/MvcTagHelper_Home/" + action);
var responseContent = await response.Content.ReadAsStringAsync();
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal(expectedMediaType, response.Content.Headers.ContentType);
if (antiForgeryPath != null)
{
var forgeryToken = AntiForgeryTestHelper.RetrieveAntiForgeryToken(responseContent, antiForgeryPath);
expectedContent = string.Format(expectedContent, forgeryToken);
}
Assert.Equal(expectedContent.Trim(), responseContent.Trim());
}
[Fact]
public async Task ValidationTagHelpers_GeneratesExpectedSpansAndDivs()
{
// Arrange
var server = TestServer.Create(_provider, _app);
var client = server.CreateClient();
var expectedContent =
await _resourcesAssembly.ReadResourceAsStringAsync
("compiler/resources/MvcTagHelpersWebSite.MvcTagHelper_Customer.Index.html");
var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/Customer/MvcTagHelper_Customer");
var nameValueCollection = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string,string>("Number", string.Empty),
new KeyValuePair<string,string>("Name", string.Empty),
new KeyValuePair<string,string>("Email", string.Empty),
new KeyValuePair<string,string>("PhoneNumber", string.Empty),
new KeyValuePair<string,string>("Password", string.Empty)
};
request.Content = new FormUrlEncodedContent(nameValueCollection);
// Act
var response = await client.SendAsync(request);
var responseContent = await response.Content.ReadAsStringAsync();
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var forgeryToken = AntiForgeryTestHelper.RetrieveAntiForgeryToken(responseContent, "Customer/MvcTagHelper_Customer");
expectedContent = string.Format(expectedContent, forgeryToken);
Assert.Equal(expectedContent.Trim(), responseContent.Trim());
}
}
}

View File

@ -35,6 +35,7 @@
"WebApiCompatShimWebSite": "1.0.0",
"Microsoft.AspNet.TestHost": "1.0.0-*",
"Microsoft.AspNet.Mvc.TestConfiguration": "1.0.0",
"MvcTagHelpersWebSite": "1.0.0",
"Microsoft.Framework.ConfigurationModel.Json": "1.0.0-*",
"xunit.runner.kre": "1.0.0-*",
"Microsoft.AspNet.WebUtilities": "1.0.0-*"

View File

@ -0,0 +1,17 @@
// 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 Microsoft.AspNet.Mvc;
namespace MvcTagHelpersWebSite.Areas.Customer.Controllers
{
[Area("Customer")]
public class MvcTagHelper_CustomerController : Controller
{
public IActionResult Index(MvcTagHelpersWebSite.Models.Customer customer)
{
return View("Customer");
}
}
}

View File

@ -0,0 +1,74 @@
// 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.Linq;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.Rendering;
using MvcTagHelpersWebSite.Models;
namespace MvcTagHelpersWebSite.Controllers
{
public class MvcTagHelper_HomeController : Controller
{
public IActionResult Order()
{
var products = new List<Product>();
products = new List<Product>();
for (int i = 7; i < 13; ++i)
{
products.Add(new Product()
{
ProductName = "Product_" + i,
Number = i,
PartNumbers = Enumerable.Range(1, 3).Select(n => string.Format("{0}-{1}", i, n))
});
}
ViewBag.Items = new SelectList(products, "Number", "ProductName", 9);
var order = new Order()
{
Shipping = "UPSP",
Customer = new Customer()
{
Key = "KeyA",
Number = 1,
Gender = Gender.Female,
Name = "NameStringValue",
},
NeedSpecialHandle = true,
PaymentMethod = new List<string> { "Check" }
};
return View(order);
}
public IActionResult Product()
{
var product = new Product()
{
HomePage = new System.Uri("http://www.contoso.com"),
Description = "Type the product description"
};
return View(product);
}
public IActionResult ProductSubmit(Product product)
{
throw new NotImplementedException();
}
public IActionResult Customer()
{
return View();
}
public IActionResult Index()
{
return View();
}
}
}

View File

@ -0,0 +1,17 @@
// 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 Microsoft.AspNet.Mvc;
using MvcTagHelpersWebSite.Models;
namespace MvcTagHelpersWebSite.Controllers
{
public class MvcTagHelper_OrderController : Controller
{
public IActionResult Submit(Order order)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,27 @@
// 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 Microsoft.AspNet.Mvc;
using MvcTagHelpersWebSite.Models;
namespace MvcTagHelpersWebSite.Controllers
{
public class MvcTagHelper_ProductController : Controller
{
public IActionResult Index()
{
throw new NotImplementedException();
}
public IActionResult Submit(Product product)
{
throw new NotImplementedException();
}
public IActionResult List()
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,56 @@
// 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 MvcTagHelpersWebSite.Models
{
public class Customer
{
[Range(1, 100)]
public int Number
{
get;
set;
}
public string Key
{
get;
set;
}
public string Name
{
get;
set;
}
[Required]
public string Password
{
get;
set;
}
[EnumDataType(typeof(Gender))]
public Gender Gender
{
get;
set;
}
public string PhoneNumber
{
get;
set;
}
[DataType(DataType.EmailAddress)]
public string Email
{
get;
set;
}
}
}

View File

@ -0,0 +1,11 @@
// 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.
namespace MvcTagHelpersWebSite.Models
{
public enum Gender
{
Male,
Female
}
}

View File

@ -0,0 +1,59 @@
// 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;
namespace MvcTagHelpersWebSite.Models
{
public class Order
{
public bool NeedSpecialHandle
{
get;
set;
}
public int OrderNumber
{
get;
set;
}
public DateTimeOffset OrderDate
{
get;
set;
}
public ICollection<string> PaymentMethod
{
get;
set;
}
public DateTime ShippingDateTime
{
get;
set;
}
public string Shipping
{
get;
set;
}
public IEnumerable<int> Products
{
get;
set;
}
public Customer Customer
{
get;
set;
}
}
}

View File

@ -0,0 +1,43 @@
// 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;
namespace MvcTagHelpersWebSite.Models
{
public class Product
{
[Required]
public string ProductName
{
get;
set;
}
public int Number
{
get;
set;
}
public string Description
{
get;
set;
}
public IEnumerable<string> PartNumbers
{
get;
set;
}
public Uri HomePage
{
get;
set;
}
}
}

View File

@ -0,0 +1,29 @@
<?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>920f8a0e-6f7d-4bbe-84ff-840b89099be6</ProjectGuid>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<AssemblyName>MvcTagHelpersWebSite</AssemblyName>
</PropertyGroup>
<PropertyGroup Label="Configuration">
<RootNamespace>MvcTagHelpersWebSite</RootNamespace>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
<DevelopmentServerPort>49646</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>

View File

@ -0,0 +1,38 @@
// 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.AspNet.Routing;
using Microsoft.Framework.DependencyInjection;
namespace MvcTagHelpersWebSite
{
public class Startup
{
public void Configure(IApplicationBuilder app)
{
var configuration = app.GetTestConfiguration();
app.UseServices(services =>
{
services.AddMvc(configuration);
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action}/{id?}",
defaults: new { controller = "MvcTagHelper_Home", action = "Index" });
routes.MapRoute(
name: "areaRoute",
template: "{area:exists}/{controller}/{action}/{id?}",
defaults: new { action = "Index" });
routes.MapRoute(
name: "productRoute",
template: "Product/{action}",
defaults: new { controller = "Product" });
});
}
}
}

View File

@ -0,0 +1,91 @@
@{
ViewBag.Title = "Home Page";
}
@addtaghelper "Microsoft.AspNet.Mvc.TagHelpers.AnchorTagHelper, Microsoft.AspNet.Mvc.TagHelpers"
<html>
<body>
<div>
<a asp-controller="Product">Product Index</a>
</div>
<div>
<a asp-controller="Product" asp-action="List">Product List</a>
</div>
<div>
<a id="MvcTagHelperTestIndex">MvcTagHelperTest Index</a>
</div>
<div>
<a asp-action="Index">Default Controller</a>
</div>
<div>
<a asp-fragment="fragment" asp-controller="Product">Product Index Fragment</a>
</div>
<div>
<a asp-controller="Product" asp-action="Submit" asp-fragment="fragment">Produt Submit Fragment</a>
</div>
<div>
<a id="MvcTagHelperTestIndexFragment" asp-fragment="fragment">
MvcTagHelperTest Index Fragment
</a>
</div>
<div>
<a asp-action="Index" asp-fragment="fragment" asp-protocol="ftp">
FTP MvcTagHelperTest Index Fragment
</a>
</div>
<div>
<a asp-controller="Product" asp-protocol="unkonwn" asp-action="List">
Unknown Protocol Product List
</a>
</div>
<div>
<a id="MvcTagHelperTestIndexProtocol" asp-protocol="">
Empty Protocol MvcTagHelperTest Index
</a>
</div>
<div>
<a asp-route="areaRoute" asp-route-area="Customer"
asp-route-controller="Customer"
asp-route-action="Index"
asp-fragment="fragment">Customer Area Customer Index</a>
</div>
<div>
<a href="/Order/List">Href Order List</a>
</div>
<div>
<a asp-controller="NonExistentController">Non-existent Controller</a>
</div>
<div>
<a asp-controller="NonExistentController" asp-fragment="fragment">
Non-existent Controller Fragment
</a>
</div>
<div>
<a asp-controller="Order" asp-action="NonExistentAction">Non-existent Action</a>
</div>
<div>
<a id="Id" asp-host="somewhere">Some Where</a>
</div>
<div>
<a asp-protocol="unknown" asp-controller="NoControll" asp-fragment="fragment">
Unknown Protocol Non-existent Controller Fragment
</a>
</div>
<div>
<a asp-route="productRoute"
asp-fragment="fragment"
asp-route-action="Submit"
asp-route-area="NonExistentArea"
asp-route-id="1">Product Route Non-existent Area Parameter</a>
</div>
<div>
<a asp-route="areaRoute"
asp-route-area="NonExistentArea"
asp-route-controller="Customer"
asp-route-action="Index"
asp-protocol="http"
asp-fragment="fragment">Non-existent Area</a>
</div>
</body>
</html>

View File

@ -0,0 +1,83 @@
@model MvcTagHelpersWebSite.Models.Order
@{
ViewBag.Title = "Order Page";
}
@addtaghelper "Microsoft.AspNet.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNet.Mvc.TagHelpers"
@addtaghelper "Microsoft.AspNet.Mvc.TagHelpers.InputTagHelper, Microsoft.AspNet.Mvc.TagHelpers"
@addtaghelper "Microsoft.AspNet.Mvc.TagHelpers.LabelTagHelper, Microsoft.AspNet.Mvc.TagHelpers"
@addtaghelper "Microsoft.AspNet.Mvc.TagHelpers.OptionTagHelper, Microsoft.AspNet.Mvc.TagHelpers"
@addtaghelper "Microsoft.AspNet.Mvc.TagHelpers.SelectTagHelper, Microsoft.AspNet.Mvc.TagHelpers"
@addtaghelper "Microsoft.AspNet.Mvc.TagHelpers.ValidationMessageTagHelper, Microsoft.AspNet.Mvc.TagHelpers"
@addtaghelper "Microsoft.AspNet.Mvc.TagHelpers.ValidationSummaryTagHelper, Microsoft.AspNet.Mvc.TagHelpers"
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<form asp-controller="MvcTagHelper_Order" asp-action="Submit" asp-anti-forgery=" true">
<div>
<label asp-for="Shipping" class="order" />
<input asp-for="Shipping" type="text" asp-format="Your shipping method is {0}" size="50" />
</div>
<div>
<label asp-for="ShippingDateTime" class="order" />
<input asp-for="ShippingDateTime" type="datetime-local" />
</div>
<div>
<label asp-for="Products" class="order" />
<select asp-for="Products" asp-items="(IEnumerable<SelectListItem>)ViewBag.Items" multiple="multiple" />
</div>
<div>
<label asp-for="OrderDate" class="order" />
<input asp-for="OrderDate" type="datetime" asp-format="{0:yyyy/MM/dd/ g}" />
</div>
<div>
<label asp-for="NeedSpecialHandle" class="order" />
<input asp-for="NeedSpecialHandle" type="checkbox" />
</div>
<div>
<label asp-for="PaymentMethod" class="order" />
<select asp-for="PaymentMethod">
<option value="Credit">Credit</option>
<option value="Check">Check</option>
</select>
</div>
<div>
<label asp-for="Customer.Number" class="order" />
<input asp-for="Customer.Number" type="number" class="form-control" />
<span asp-validation-for="Customer.Number" />
</div>
<div>
<label asp-for="Customer.Name" class="order" />
<input asp-for="Customer.Name" type="text" />
</div>
<div>
<label asp-for="Customer.Email" class="order" />
<input asp-for="Customer.Email" type="email" />
<span asp-validation-for="Customer.Email" />
</div>
<div>
<label asp-for="Customer.PhoneNumber" class="order" />
<input asp-for="Customer.PhoneNumber" type="tel" />
</div>
<div>
<label asp-for="Customer.Password" class="order" />
<input asp-for="Customer.Password" type="password" class="form-control" />
<span asp-validation-for="Customer.Password" />
</div>
<div>
<label asp-for="Customer.Gender" class="order" />
<input asp-for="Customer.Gender" type="radio" value="Male" /> Male
<input asp-for="Customer.Gender" type="radio" value="Female" /> Female
<span asp-validation-for="Customer.Gender" />
</div>
<div asp-validation-summary="All" class="order" />
<input type="hidden" asp-for="Customer.Key" />
<input type="submit" />
</form>
</body>
</html>

View File

@ -0,0 +1,27 @@
@model MvcTagHelpersWebSite.Models.Product
@{
ViewBag.Title = "Product Page";
}
@addtaghelper "Microsoft.AspNet.Mvc.TagHelpers"
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<form asp-controller="MvcTagHelper_Home" asp-route-action="ProductSubmit" asp-anti-forgery="false" method="get">
<div>
<label asp-for="HomePage" class="product" />
<input asp-for="HomePage" type="url" size="50" />
</div>
<div>
<label asp-for="Description" class="product" />
<textarea asp-for="Description" rows="4" cols="50" class="product" />
</div>
<input type="submit" />
</form>
</body>
</html>

View File

@ -0,0 +1,46 @@
@model MvcTagHelpersWebSite.Models.Customer
@{
ViewBag.Title = "Customer Page";
}
@addtaghelper "Microsoft.AspNet.Mvc.TagHelpers"
<html>
<body>
<form asp-route-area="Customer" asp-controller="MvcTagHelper_Customer" asp-action="Index">
<div>
<label asp-for="Number" class="order" />
<input asp-for="Number" type="number" class="form-control" />
<span asp-validation-for="Number" />
</div>
<div>
<label asp-for="Name" class="order" />
<input asp-for="Name" type="text" />
</div>
<div>
<label asp-for="Email" class="order" />
<input asp-for="Email" type="email" />
<span asp-validation-for="Email" />
</div>
<div>
<label asp-for="PhoneNumber" class="order" />
<input asp-for="PhoneNumber" type="tel" />
</div>
<div>
<label asp-for="Password" class="order" />
<input asp-for="Password" type="password" class="form-control" />
<span asp-validation-for="Password" />
</div>
<div>
<label asp-for="Gender" class="order" />
<input asp-for="Gender" type="radio" value="Male" /> Male
<input asp-for="Gender" type="radio" value="Female" /> Female
<span asp-validation-for="Gender" />
</div>
<div asp-validation-summary="All" class="order" />
<div asp-validation-summary="ModelOnly" class="order" />
<input type="submit" />
</form>
</body>
</html>

View File

@ -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.TagHelpers": "6.0.0-*",
"Microsoft.AspNet.Mvc.TestConfiguration": "1.0.0",
"Microsoft.AspNet.Server.IIS": "1.0.0-*",
"Microsoft.AspNet.Server.WebListener": "1.0.0-*"
},
"frameworks": {
"aspnet50": { },
"aspnetcore50": { }
},
"webroot": "wwwroot"
}

Binary file not shown.