-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Add TagHelperSample.Web #1289
Add TagHelperSample.Web #1289
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
| ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using Microsoft.AspNet.Mvc; | ||
using Microsoft.AspNet.Mvc.Rendering; | ||
using TagHelperSample.Web.Models; | ||
|
||
namespace TagHelperSample.Web.Controllers | ||
{ | ||
public class HomeController : Controller | ||
{ | ||
private static readonly IEnumerable<SelectListItem> _items = new SelectList(Enumerable.Range(7, 13)); | ||
private static readonly Dictionary<int, User> _users = new Dictionary<int, User>(); | ||
private static int _next; | ||
|
||
public HomeController() | ||
{ | ||
// Unable to set ViewBag from constructor. Does this work in MVC 5.2? | ||
////ViewBag.Items = _items; | ||
} | ||
|
||
// GET: /<controller>/ | ||
public IActionResult Index() | ||
{ | ||
return View(_users.Values); | ||
} | ||
|
||
// GET: /Home/Create | ||
public IActionResult Create() | ||
{ | ||
ViewBag.Items = _items; | ||
return View(); | ||
} | ||
|
||
// POST: Home/Create | ||
[HttpPost] | ||
public IActionResult Create(User user) | ||
{ | ||
if (user != null && ModelState.IsValid) | ||
{ | ||
var id = _next++; | ||
user.Id = id; | ||
_users[id] = user; | ||
return RedirectToAction("Index"); | ||
} | ||
|
||
ViewBag.Items = _items; | ||
return View(); | ||
} | ||
|
||
// GET: /Home/Edit/5 | ||
public IActionResult Edit(int id) | ||
{ | ||
User user; | ||
_users.TryGetValue(id, out user); | ||
|
||
ViewBag.Items = _items; | ||
return View(user); | ||
} | ||
|
||
// POST: Home/Edit/5 | ||
[HttpPost] | ||
public IActionResult Edit(int id, User user) | ||
{ | ||
if (user != null && id == user.Id && _users.ContainsKey(id) && ModelState.IsValid) | ||
{ | ||
_users[id] = user; | ||
return RedirectToAction("Index"); | ||
} | ||
|
||
ViewBag.Items = _items; | ||
return View(); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
| ||
using System; | ||
|
||
namespace TagHelperSample.Web.Models | ||
{ | ||
public class User | ||
{ | ||
public int Id { get; set; } | ||
|
||
public string Name { get; set; } | ||
|
||
public string Blurb { get; set; } | ||
|
||
public DateTimeOffset DateOfBirth { get; set; } | ||
|
||
public int YearsEmployeed { get; set; } | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
| ||
using Microsoft.AspNet.Builder; | ||
using Microsoft.Framework.DependencyInjection; | ||
|
||
namespace TagHelperSample.Web | ||
{ | ||
public class Startup | ||
{ | ||
public void Configure(IApplicationBuilder app) | ||
{ | ||
app.UseServices(services => services.AddMvc()); | ||
app.UseMvc(); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?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>2223120f-d675-40da-8cd8-11dc14a0b2c7</ProjectGuid> | ||
<OutputType>Web</OutputType> | ||
<RootNamespace>TagHelperSample.Web</RootNamespace> | ||
</PropertyGroup> | ||
<PropertyGroup> | ||
<SchemaVersion>2.0</SchemaVersion> | ||
<DevelopmentServerPort>31726</DevelopmentServerPort> | ||
</PropertyGroup> | ||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" /> | ||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
| ||
@using TagHelperSample.Web.Models | ||
@model User | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note: Once the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not actionable in this PR |
||
<h2>Create</h2> | ||
|
||
@* anti-forgery is on by default *@ | ||
@* form will special-case anything that looks like a URI i.e. contains a '/' or doesn't match an action *@ | ||
<form anti-forgery="false" action="Create"> | ||
<div class="form-horizontal"> | ||
@* validation summary tag helper will target just <div/> elements and append the list of errors *@ | ||
@* - i.e. this helper, like <select/> helper has ContentBehavior.Append *@ | ||
@* validation-model-errors-only="true" implies validation-summary="true" *@ | ||
@* helper does nothing if model is valid and (client-side validation is disabled or validation-model-errors-only="true") *@ | ||
@* don't need a bound attribute to match Html.ValidationSummary()'s headerTag parameter; users wrap message as they wish *@ | ||
@* initially at least, will not remove the <div/> if list isn't generated *@ | ||
@* - should helper remove the <div/> if list isn't generated? *@ | ||
@* - (Html.ValidationSummary returns empty string despite non-empty message parameter) *@ | ||
<div validation-summary="true" validation-model-errors-only="true"> | ||
<span style="color:red">This is my message</span> | ||
</div> | ||
|
||
@* element will have correct name and id attributes for Id property. unusual part is the constant value. *@ | ||
@* - the helper will _not_ override the user-specified "value" attribute *@ | ||
<input type="hidden" for="Id" value="0" /> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this file isn't much different from Edit.cshtml but I only use a user-specified HTML attributes (that helper would normally generate) here. suspect "class" attribute would be merged but all other user-specified HTML attributes would just win. |
||
|
||
<div class="form-group"> | ||
@* no special-case for the "for" attribute; may eventually need to opt out on per-element basis here and in <form/> *@ | ||
<label for="Name" class="control-label col-md-2" style="color:blue" /> | ||
<div class="col-md-10"> | ||
<input type="text" for="Name" style="color:blue" /> | ||
<span validation-for="Name" style="color:blue" /> | ||
</div> | ||
</div> | ||
<div class="form-group"> | ||
<label for="DateOfBirth" class="control-label col-md-2" /> | ||
<div class="col-md-10"> | ||
@* will automatically infer type="date" (reused HTML attribute) and format="{0:d}" (optional bound attribute) *@ | ||
<input for="DateOfBirth" /> | ||
<span validation-for="DateOfBirth">How old are you?</span> | ||
</div> | ||
</div> | ||
<div class="form-group"> | ||
<label for="YearsEmployeed" class="control-label col-md-2" /> | ||
<div class="col-md-10"> | ||
@* <select/> tag helper has ContentBehavior.Append -- items render after static options *@ | ||
<select for="YearsEmployeed" items="(IEnumerable<SelectListItem>)ViewBag.Items" size="2" class="form-control"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "items" attribute needn't be so ugly. I just didn't switch from |
||
@* schedule-wise option tag helper (which adds "selected" attribute to static <option/>s) comes after helpers *@ | ||
@* - static use of "selected" attribute may cause HTML errors if in a single-selection <select/> *@ | ||
@* - @NTaylorMullen thinks <option/> tag helper could tell <select/> helper not to select anything from "items" *@ | ||
@* - wouldn't help if user selected one static <option/> and expression indicated another, especially one earlier in the <select/> *@ | ||
@* - may need a "default" bound parameter on the <select/> to avoid these cases and maintain "don't override" *@ | ||
<option value="" selected="selected">Why didn't you select anything?</option> | ||
<optgroup label="Newby"> | ||
<option value="0">Less than 1</option> | ||
<option value="1">1</option> | ||
</optgroup> | ||
<option value="2">2</option> | ||
<option value="3">3</option> | ||
<option value="4">4</option> | ||
<option value="5">5</option> | ||
<option value="6">6</option> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. note user should not specify There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comments in Create.cshtml revise this thinking somewhat |
||
</select> | ||
|
||
@* targets only <span/> in Beta; does not support equivalent of Html.ValidationMessageFor()'s tag parameter *@ | ||
@* - may eventually either support additional tags e.g. <p/> and <div/> or all tags /> *@ | ||
<span validation-for="YearsEmployeed" /> | ||
</div> | ||
</div> | ||
<div class="form-group"> | ||
<label for="Blurb" class="control-label col-md-2" /> | ||
<div class="col-md-10"> | ||
<textarea rows="4" for="Blurb"></textarea> | ||
<span validation-for="Blurb" /> | ||
</div> | ||
</div> | ||
|
||
<div class="form-group"> | ||
<div class="col-md-offset-2 col-md-10"> | ||
@* this <input/> lacks a "for" attribute and will not be changed by the <input/> tag helper *@ | ||
<input type="submit" value="Create" class="btn btn-default" /> | ||
</div> | ||
</div> | ||
</div> | ||
</form> | ||
|
||
<div> | ||
<a action="Index">Back to list</a> | ||
</div> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
| ||
@using TagHelperSample.Web.Models | ||
@model User | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note: Once the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not actionable in this PR |
||
<h2>Edit</h2> | ||
|
||
<form> | ||
<div class="form-horizontal"> | ||
<div validation-summary="true"/> | ||
<input type="hidden" for="Id" /> | ||
|
||
<div class="form-group"> | ||
<label for="Name" class="control-label col-md-2" /> | ||
<div class="col-md-10"> | ||
<input type="text" for="Name" /> | ||
<span validation-for="Name" /> | ||
</div> | ||
</div> | ||
<div class="form-group"> | ||
<label for="DateOfBirth" class="control-label col-md-2" /> | ||
<div class="col-md-10"> | ||
<input type="date" for="DateOfBirth" format="{0:d}" /> | ||
<span validation-for="DateOfBirth">How old are you?</span> | ||
</div> | ||
</div> | ||
<div class="form-group"> | ||
<label for="YearsEmployeed" class="control-label col-md-2" /> | ||
<div class="col-md-10"> | ||
<select for="YearsEmployeed" items="(IEnumerable<SelectListItem>)ViewBag.Items" size="2" class="form-control"> | ||
<optgroup label="Newby"> | ||
<option value="0">Less than 1</option> | ||
<option value="1">1</option> | ||
</optgroup> | ||
<option value="2">2</option> | ||
<option value="3">3</option> | ||
<option value="4">4</option> | ||
<option value="5">5</option> | ||
<option value="6">6</option> | ||
</select> | ||
<span validation-for="YearsEmployeed" /> | ||
</div> | ||
</div> | ||
<div class="form-group"> | ||
<label for="Blurb" class="control-label col-md-2" /> | ||
<div class="col-md-10"> | ||
<textarea rows="4" for="Blurb"></textarea> | ||
<span validation-for="Blurb" /> | ||
</div> | ||
</div> | ||
|
||
<div class="form-group"> | ||
<div class="col-md-offset-2 col-md-10"> | ||
<input type="submit" value="Save" class="btn btn-default" /> | ||
</div> | ||
</div> | ||
</div> | ||
</form> | ||
|
||
<div> | ||
<a action="Index">Back to list</a> | ||
</div> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
| ||
@using TagHelperSample.Web.Models | ||
@model IEnumerable<User> | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note: Once the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not actionable in this PR There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we have an idea of the exact syntax it would be to add the built-in tag helpers? Or are those always present? Or? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Opt-in: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it, thanks! |
||
<h2>Index</h2> | ||
<p> | ||
<a action="Create">Create New</a> | ||
</p> | ||
|
||
@if (Model != null && Model.Count() != 0) | ||
{ | ||
<div class="form-horizontal"> | ||
@foreach (var item in Model) | ||
{ | ||
<div class="form-group"> | ||
<label for="@item.Name" /> | ||
<input type="text" for="@item.Name" disabled="disabled" readonly="readonly" /> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note: The current plan results in this not working until after beta. Might not be valuable to have until then since it'll just cause compile errors on the view. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👎 this sample is aspirational and uses lots of unimplemented features |
||
</div> | ||
<div class="form-group"> | ||
<label for="@item.DateOfBirth" /> | ||
<input type="date" for="@item.DateOfBirth" disabled="disabled" readonly="readonly" /> | ||
</div> | ||
<div class="form-group"> | ||
<label for="@item.YearsEmployeed" /> | ||
<input type="number" for="@item.YearsEmployeed" disabled="disabled" readonly="readonly" /> | ||
</div> | ||
<div class="form-group"> | ||
<label for="@item.Blurb" /> | ||
<textarea rows="4" for="@item.Blurb" disabled="disabled" readonly="readonly" /> | ||
</div> | ||
|
||
<a action="Edit" controller="Home" route="MyRouteName" route-id="@item.Id">Edit</a> | ||
} | ||
</div> | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"compilationOptions": { | ||
"warningsAsErrors": true | ||
}, | ||
"dependencies": { | ||
"Microsoft.AspNet.Mvc": "6.0.0-*", | ||
"Microsoft.AspNet.Server.IIS": "1.0.0-*", | ||
"Microsoft.AspNet.Server.WebListener": "1.0.0-*", | ||
"Microsoft.Framework.ConfigurationModel": "1.0.0-*" | ||
}, | ||
"commands": { | ||
"web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:5001" | ||
}, | ||
"frameworks": { | ||
"aspnet50": { | ||
"dependencies": { | ||
"Microsoft.Framework.ConfigurationModel.Json": "1.0.0-*" | ||
} | ||
}, | ||
"aspnetcore50": { | ||
"dependencies": { } | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's set via the
DefaultControllerActivator
from an[Activate]
attribute which is why it doesn't work today (activates the controller after it's been instantiated).Does work in 5.2 though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will track as a straight-up MVC 6.0 bug that this NREs