Add another view to MvcTagHelpersWebSite using HTML helpers
- with some `<text>` hacks, generated HTML is almost identical to tag helper version - attribute order (HTML helpers consistently order alphabetically) is primary difference - bit more testing, therefore related to #453 nits: - remove some trailing whitespace - clean up style in `MvcTagHelperTest[s]` and `MvcTagHelper_HomeController` - e.g. more init syntax, fewer duplicate variables - correct "MvcTagHelperTest~~s~~" file / class name - remove unused `Order.OrderNumber` property in MvcTagHelpersWebSite project - correct one spelling mistake
This commit is contained in:
parent
df0d556fcc
commit
bf00f478e5
|
|
@ -0,0 +1,76 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<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 id="Shipping" name="Shipping" size="50" type="text" value="Your shipping method is UPSP" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="order" for="ShippingDateTime">ShippingDateTime</label>
|
||||||
|
<input id="ShippingDateTime" name="ShippingDateTime" type="datetime-local" value="01/01/0001 00:00:00" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="order" for="Products">Products</label>
|
||||||
|
|
||||||
|
<select id="Products" multiple="multiple" name="Products"><option value="0">Product_0</option>
|
||||||
|
<option value="1">Product_1</option>
|
||||||
|
<option selected="selected" value="2">Product_2</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="order" for="OrderDate">OrderDate</label>
|
||||||
|
<input id="OrderDate" name="OrderDate" type="datetime" 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 selected="selected" value="Check">Check</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="order" for="Customer_Number">Number</label>
|
||||||
|
<input class="form-control" 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" type="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 id="Customer_Name" name="Customer.Name" type="text" value="NameStringValue" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="order" for="Customer_Email">Email</label>
|
||||||
|
<input id="Customer_Email" name="Customer.Email" type="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 id="Customer_PhoneNumber" name="Customer.PhoneNumber" type="tel" value="" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="order" for="Customer_Password">Password</label>
|
||||||
|
<input class="form-control" data-val="true" data-val-required="The Password field is required." id="Customer_Password" name="Customer.Password" type="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 id="Customer_Gender" name="Customer.Gender" type="radio" value="Male" /> Male
|
||||||
|
<input checked="checked" id="Customer_Gender" name="Customer.Gender" type="radio" value="Female" /> Female
|
||||||
|
<span class="field-validation-valid" data-valmsg-for="Customer.Gender" data-valmsg-replace="true"></span>
|
||||||
|
</div>
|
||||||
|
<div class="validation-summary-valid order" data-valmsg-summary="true"><ul><li style="display:none"></li>
|
||||||
|
</ul></div>
|
||||||
|
<input id="Customer_Key" name="Customer.Key" type="hidden" value="KeyA" />
|
||||||
|
<input type="submit"></input>
|
||||||
|
<input name="__RequestVerificationToken" type="hidden" value="{0}" /></form>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -54,7 +54,7 @@
|
||||||
<div>
|
<div>
|
||||||
<label class="product" for="z2__Description">Description</label>
|
<label class="product" for="z2__Description">Description</label>
|
||||||
<textarea rows="4" cols="50" class="product" id="z2__Description" name="[2].Description">
|
<textarea rows="4" cols="50" class="product" id="z2__Description" name="[2].Description">
|
||||||
Product_2 desription</textarea>
|
Product_2 description</textarea>
|
||||||
</div> <input type="submit"></input>
|
</div> <input type="submit"></input>
|
||||||
</form></body>
|
</form></body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -15,23 +15,26 @@ using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.FunctionalTests
|
namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||||
{
|
{
|
||||||
public class MvcTagHelpersTests
|
public class MvcTagHelpersTest
|
||||||
{
|
{
|
||||||
private readonly IServiceProvider _provider = TestHelper.CreateServices("MvcTagHelpersWebSite");
|
private readonly IServiceProvider _provider = TestHelper.CreateServices("MvcTagHelpersWebSite");
|
||||||
private readonly Action<IApplicationBuilder> _app = new Startup().Configure;
|
private readonly Action<IApplicationBuilder> _app = new Startup().Configure;
|
||||||
private static readonly Assembly _resourcesAssembly = typeof(MvcTagHelpersTests).GetTypeInfo().Assembly;
|
private static readonly Assembly _resourcesAssembly = typeof(MvcTagHelpersTest).GetTypeInfo().Assembly;
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("Index", null)]
|
[InlineData("Index", null)]
|
||||||
|
// Test ability to generate nearly identical HTML with MVC tag and HTML helpers.
|
||||||
|
// Only attribute order should differ.
|
||||||
[InlineData("Order", "/MvcTagHelper_Order/Submit")]
|
[InlineData("Order", "/MvcTagHelper_Order/Submit")]
|
||||||
|
[InlineData("OrderUsingHtmlHelpers", "/MvcTagHelper_Order/Submit")]
|
||||||
[InlineData("Product", null)]
|
[InlineData("Product", null)]
|
||||||
[InlineData("Customer", "/Customer/MvcTagHelper_Customer")]
|
[InlineData("Customer", "/Customer/MvcTagHelper_Customer")]
|
||||||
// Testing InputTagHelpers invoked in the partial views
|
// Testing InputTagHelpers invoked in the partial views
|
||||||
[InlineData("ProductList", null)]
|
[InlineData("ProductList", null)]
|
||||||
// Testing MvcTagHelpers invoked in the editor templates with the HTML helpers
|
// Testing MvcTagHelpers invoked in the editor templates with the HTML helpers
|
||||||
[InlineData("EmployeeList", null)]
|
[InlineData("EmployeeList", null)]
|
||||||
// Testing SelectTagHelper with Html.BeginForm
|
// Testing SelectTagHelper with Html.BeginForm
|
||||||
[InlineData("CreateWarehouse", null)]
|
[InlineData("CreateWarehouse", null)]
|
||||||
// Testing the HTML helpers with FormTagHelper
|
// Testing the HTML helpers with FormTagHelper
|
||||||
[InlineData("EditWarehouse", null)]
|
[InlineData("EditWarehouse", null)]
|
||||||
// Testing the EnvironmentTagHelper
|
// Testing the EnvironmentTagHelper
|
||||||
|
|
@ -45,9 +48,8 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||||
|
|
||||||
// The K runtime compiles every file under compiler/resources as a resource at runtime with the same name
|
// 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.
|
// as the file name, in order to update a baseline you just need to change the file in that folder.
|
||||||
var expectedContent =
|
var expectedContent = await _resourcesAssembly.ReadResourceAsStringAsync(
|
||||||
await _resourcesAssembly.ReadResourceAsStringAsync
|
"compiler/resources/MvcTagHelpersWebSite.MvcTagHelper_Home." + action + ".html");
|
||||||
("compiler/resources/MvcTagHelpersWebSite.MvcTagHelper_Home." + action + ".html");
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
// The host is not important as everything runs in memory and tests are isolated from each other.
|
// The host is not important as everything runs in memory and tests are isolated from each other.
|
||||||
|
|
@ -72,9 +74,8 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||||
// Arrange
|
// Arrange
|
||||||
var server = TestServer.Create(_provider, _app);
|
var server = TestServer.Create(_provider, _app);
|
||||||
var client = server.CreateClient();
|
var client = server.CreateClient();
|
||||||
var expectedContent =
|
var expectedContent = await _resourcesAssembly.ReadResourceAsStringAsync(
|
||||||
await _resourcesAssembly.ReadResourceAsStringAsync
|
"compiler/resources/MvcTagHelpersWebSite.MvcTagHelper_Customer.Index.html");
|
||||||
("compiler/resources/MvcTagHelpersWebSite.MvcTagHelper_Customer.Index.html");
|
|
||||||
|
|
||||||
var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/Customer/MvcTagHelper_Customer");
|
var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/Customer/MvcTagHelper_Customer");
|
||||||
var nameValueCollection = new List<KeyValuePair<string, string>>
|
var nameValueCollection = new List<KeyValuePair<string, string>>
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using Microsoft.AspNet.Mvc;
|
using Microsoft.AspNet.Mvc;
|
||||||
using Microsoft.AspNet.Mvc.Rendering;
|
using Microsoft.AspNet.Mvc.Rendering;
|
||||||
using MvcTagHelpersWebSite.Models;
|
using MvcTagHelpersWebSite.Models;
|
||||||
|
|
@ -12,48 +11,60 @@ namespace MvcTagHelpersWebSite.Controllers
|
||||||
{
|
{
|
||||||
public class MvcTagHelper_HomeController : Controller
|
public class MvcTagHelper_HomeController : Controller
|
||||||
{
|
{
|
||||||
private readonly List<Product> _products = new List<Product>();
|
private readonly List<Product> _products = new List<Product>
|
||||||
|
|
||||||
public MvcTagHelper_HomeController()
|
|
||||||
{
|
{
|
||||||
_products.Add(new Product
|
new Product
|
||||||
{
|
{
|
||||||
ProductName = "Product_0",
|
ProductName = "Product_0",
|
||||||
Number = 0,
|
Number = 0,
|
||||||
HomePage = new Uri("http://www.contoso.com")
|
HomePage = new Uri("http://www.contoso.com")
|
||||||
});
|
},
|
||||||
_products.Add(new Product
|
new Product
|
||||||
{
|
{
|
||||||
ProductName = "Product_1",
|
ProductName = "Product_1",
|
||||||
Number = 1,
|
Number = 1,
|
||||||
});
|
},
|
||||||
_products.Add(new Product
|
new Product
|
||||||
{
|
{
|
||||||
ProductName = "Product_2",
|
ProductName = "Product_2",
|
||||||
Number = 2,
|
Number = 2,
|
||||||
Description = "Product_2 desription"
|
Description = "Product_2 description"
|
||||||
});
|
},
|
||||||
|
};
|
||||||
|
private readonly IEnumerable<SelectListItem> _productsList;
|
||||||
|
private readonly IEnumerable<SelectListItem> _productsListWithSelection;
|
||||||
|
private readonly Order _order = new Order
|
||||||
|
{
|
||||||
|
Shipping = "UPSP",
|
||||||
|
Customer = new Customer
|
||||||
|
{
|
||||||
|
Key = "KeyA",
|
||||||
|
Number = 1,
|
||||||
|
Gender = Gender.Female,
|
||||||
|
Name = "NameStringValue",
|
||||||
|
},
|
||||||
|
NeedSpecialHandle = true,
|
||||||
|
PaymentMethod = new List<string> { "Check" },
|
||||||
|
};
|
||||||
|
|
||||||
|
public MvcTagHelper_HomeController()
|
||||||
|
{
|
||||||
|
_productsList = new SelectList(_products, "Number", "ProductName");
|
||||||
|
_productsListWithSelection = new SelectList(_products, "Number", "ProductName", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IActionResult Order()
|
public IActionResult Order()
|
||||||
{
|
{
|
||||||
ViewBag.Items = new SelectList(_products, "Number", "ProductName", 2);
|
ViewBag.Items = _productsListWithSelection;
|
||||||
|
|
||||||
var order = new Order
|
return View(_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 OrderUsingHtmlHelpers()
|
||||||
|
{
|
||||||
|
ViewBag.Items = _productsListWithSelection;
|
||||||
|
|
||||||
|
return View(_order);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IActionResult Product()
|
public IActionResult Product()
|
||||||
|
|
@ -63,6 +74,7 @@ namespace MvcTagHelpersWebSite.Controllers
|
||||||
HomePage = new System.Uri("http://www.contoso.com"),
|
HomePage = new System.Uri("http://www.contoso.com"),
|
||||||
Description = "Type the product description"
|
Description = "Type the product description"
|
||||||
};
|
};
|
||||||
|
|
||||||
return View(product);
|
return View(product);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,34 +100,35 @@ namespace MvcTagHelpersWebSite.Controllers
|
||||||
|
|
||||||
public IActionResult EmployeeList()
|
public IActionResult EmployeeList()
|
||||||
{
|
{
|
||||||
var employees = new List<Employee>();
|
var employees = new List<Employee>
|
||||||
|
|
||||||
employees.Add(new Employee
|
|
||||||
{
|
{
|
||||||
Name = "EmployeeName_0",
|
new Employee
|
||||||
Number = 0,
|
{
|
||||||
Address = "Employee_0 address"
|
Name = "EmployeeName_0",
|
||||||
});
|
Number = 0,
|
||||||
employees.Add(new Employee
|
Address = "Employee_0 address"
|
||||||
{
|
},
|
||||||
Name = "EmployeeName_1",
|
new Employee
|
||||||
Number = 1,
|
{
|
||||||
OfficeNumber = "1002",
|
Name = "EmployeeName_1",
|
||||||
Gender = Gender.Female
|
Number = 1,
|
||||||
});
|
OfficeNumber = "1002",
|
||||||
employees.Add(new Employee
|
Gender = Gender.Female
|
||||||
{
|
},
|
||||||
Name = "EmployeeName_2",
|
new Employee
|
||||||
Number = 2,
|
{
|
||||||
Remote = true
|
Name = "EmployeeName_2",
|
||||||
});
|
Number = 2,
|
||||||
|
Remote = true
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
return View(employees);
|
return View(employees);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IActionResult CreateWarehouse()
|
public IActionResult CreateWarehouse()
|
||||||
{
|
{
|
||||||
ViewBag.Items = new SelectList(_products, "Number", "ProductName", 9);
|
ViewBag.Items = _productsList;
|
||||||
|
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
|
|
@ -134,6 +147,7 @@ namespace MvcTagHelpersWebSite.Controllers
|
||||||
Gender = Gender.Female
|
Gender = Gender.Female
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return View(warehouse);
|
return View(warehouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,12 +14,6 @@ namespace MvcTagHelpersWebSite.Models
|
||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int OrderNumber
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DateTimeOffset OrderDate
|
public DateTimeOffset OrderDate
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
@using MvcTagHelpersWebSite.Models
|
||||||
|
@model Gender
|
||||||
|
@Html.RadioButtonFor(m => m, value: "Male") Male
|
||||||
|
@Html.RadioButtonFor(m => m, value: "Female") Female
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
@model MvcTagHelpersWebSite.Models.Order
|
||||||
|
|
||||||
|
@{
|
||||||
|
ViewBag.Title = "Order Page";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title></title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
@* Use comments and <text/> elements to force whitespace in generated HTML. *@@using (
|
||||||
|
Html.BeginForm(actionName: "Submit", controllerName: "MvcTagHelper_Order"))
|
||||||
|
{<text></text>
|
||||||
|
<div>
|
||||||
|
@Html.LabelFor(m => m.Shipping, htmlAttributes: new { @class = "order" })
|
||||||
|
@Html.TextBoxFor(m => m.Shipping, format: "Your shipping method is {0}", htmlAttributes: new { size = "50" })
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
@Html.LabelFor(m => m.ShippingDateTime, htmlAttributes: new { @class = "order" })
|
||||||
|
@Html.TextBoxFor(m => m.ShippingDateTime, htmlAttributes: new { type = "datetime-local" })
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
@Html.LabelFor(m => m.Products, htmlAttributes: new { @class = "order" })
|
||||||
|
@{ var productSelectList = (IEnumerable<SelectListItem>)ViewBag.Items; }
|
||||||
|
@Html.ListBoxFor(m => m.Products, productSelectList)
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
@Html.LabelFor(m => m.OrderDate, htmlAttributes: new { @class = "order" })
|
||||||
|
@Html.TextBoxFor(m => m.OrderDate, format: "{0:yyyy/MM/dd/ g}", htmlAttributes: new { type = "datetime" })
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
@Html.LabelFor(m => m.NeedSpecialHandle, htmlAttributes: new { @class = "order" })
|
||||||
|
@Html.CheckBoxFor(m => m.NeedSpecialHandle)
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
@Html.LabelFor(m => m.PaymentMethod, htmlAttributes: new { @class = "order" })
|
||||||
|
@Html.ListBoxFor(m => m.PaymentMethod, selectList: new SelectList(new[] { new { value = "Credit" }, new { value = "Check" } }, dataValueField: "value", dataTextField: "value"))
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
@Html.LabelFor(m => m.Customer.Number, htmlAttributes: new { @class = "order" })
|
||||||
|
@Html.TextBoxFor(m => m.Customer.Number, htmlAttributes: new { type = "number", @class = "form-control" })
|
||||||
|
@Html.ValidationMessageFor(m => m.Customer.Number)
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
@Html.LabelFor(m => m.Customer.Name, htmlAttributes: new { @class = "order" })
|
||||||
|
@Html.TextBoxFor(m => m.Customer.Name)
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
@Html.LabelFor(m => m.Customer.Email, htmlAttributes: new { @class = "order" })
|
||||||
|
@Html.TextBoxFor(m => m.Customer.Email, htmlAttributes: new { type = "email" })
|
||||||
|
@Html.ValidationMessageFor(m => m.Customer.Email)
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
@Html.LabelFor(m => m.Customer.PhoneNumber, htmlAttributes: new { @class = "order" })
|
||||||
|
@Html.TextBoxFor(m => m.Customer.PhoneNumber, htmlAttributes: new { type = "tel" })
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
@Html.LabelFor(m => m.Customer.Password, htmlAttributes: new { @class = "order" })
|
||||||
|
@Html.PasswordFor(m => m.Customer.Password, htmlAttributes: new { @class = "form-control" })
|
||||||
|
@Html.ValidationMessageFor(m => m.Customer.Password)
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
@Html.LabelFor(m => m.Customer.Gender, htmlAttributes: new { @class = "order" })
|
||||||
|
@Html.EditorFor(model => model.Customer.Gender, templateName: "GenderUsingHtmlHelpers")
|
||||||
|
@Html.ValidationMessageFor(m => m.Customer.Gender)
|
||||||
|
</div><text>
|
||||||
|
</text>@Html.ValidationSummary(message: null, htmlAttributes: new { @class = "order" })<text>
|
||||||
|
</text>@Html.HiddenFor(m => m.Customer.Key)<text></text>
|
||||||
|
<input type="submit"></input><text>
|
||||||
|
</text>@Html.AntiForgeryToken();
|
||||||
|
}@**@
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
Reference in New Issue