logger)
+ {
+ _logger = logger;
+ }
+
+ public IActionResult Index()
+ {
+ return View();
+ }
+
+ public IActionResult Privacy()
+ {
+ return View();
+ }
+
+ [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
+ public IActionResult Error()
+ {
+ return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
+ }
+ }
+}
diff --git a/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Controllers/WeatherForecastController.cs b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Controllers/WeatherForecastController.cs
new file mode 100644
index 000000000000..3d8ef58526fc
--- /dev/null
+++ b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Controllers/WeatherForecastController.cs
@@ -0,0 +1,65 @@
+using System.Globalization;
+using BindTryParseMVC.Models;
+using Microsoft.AspNetCore.Mvc;
+
+namespace BindTryParseMVC.Controllers
+{
+ public class WeatherForecastController : Controller
+ {
+ private static readonly string[] Summaries = new[]
+ {
+ "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
+ };
+
+ ///
+ /// /WeatherForecast?culture=en-GB
+ ///
+ ///
+ ///
+ public IActionResult Index(Culture? culture)
+ {
+ var weatherForecasts = Enumerable
+ .Range(1, 5).Select(index => new WeatherForecast
+ {
+ Date = DateTime.Now.AddDays(index),
+ TemperatureC = Random.Shared.Next(-20, 55),
+ Summary = Summaries[Random.Shared.Next(Summaries.Length)]
+ })
+ .Select(wf => new WeatherForecastViewModel
+ {
+ Date = wf.Date.ToString(new CultureInfo(culture?.DisplayName ?? "en-US")),
+ TemperatureC = wf.TemperatureC,
+ TemperatureF = wf.TemperatureF,
+ Summary = wf.Summary
+ });
+
+ return View(weatherForecasts);
+ }
+
+ ///
+ /// /WeatherForecast/Range?range=07/12/2022-07/14/2022
+ ///
+ ///
+ ///
+ public IActionResult Range(DateRange? range)
+ {
+ var weatherForecasts = Enumerable
+ .Range(1, 5).Select(index => new WeatherForecast
+ {
+ Date = DateTime.Now.AddDays(index),
+ TemperatureC = Random.Shared.Next(-20, 55),
+ Summary = Summaries[Random.Shared.Next(Summaries.Length)]
+ })
+ .Where(wf => DateOnly.FromDateTime(wf.Date) >= (range?.From ?? DateOnly.MinValue) && DateOnly.FromDateTime(wf.Date) <= (range?.To ?? DateOnly.MaxValue))
+ .Select(wf => new WeatherForecastViewModel
+ {
+ Date = wf.Date.ToString(),
+ TemperatureC = wf.TemperatureC,
+ TemperatureF = wf.TemperatureF,
+ Summary = wf.Summary
+ });
+
+ return View(weatherForecasts);
+ }
+ }
+}
diff --git a/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Models/Culture.cs b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Models/Culture.cs
new file mode 100644
index 000000000000..c762e9407074
--- /dev/null
+++ b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Models/Culture.cs
@@ -0,0 +1,27 @@
+namespace BindTryParseMVC.Models
+{
+ public class Culture
+ {
+ public string? DisplayName { get; }
+
+ public Culture(string displayName)
+ {
+ if (string.IsNullOrEmpty(displayName))
+ throw new ArgumentNullException(nameof(displayName));
+
+ DisplayName = displayName;
+ }
+
+ public static bool TryParse(string? value, out Culture? result)
+ {
+ if (value is null)
+ {
+ result = default;
+ return false;
+ }
+
+ result = new Culture(value);
+ return true;
+ }
+ }
+}
diff --git a/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Models/DateRange.cs b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Models/DateRange.cs
new file mode 100644
index 000000000000..23195680d533
--- /dev/null
+++ b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Models/DateRange.cs
@@ -0,0 +1,32 @@
+namespace BindTryParseMVC.Models
+{
+ public class DateRange
+ {
+ public DateOnly? From { get; }
+ public DateOnly? To { get; }
+
+ public DateRange(string from, string to)
+ {
+ if (string.IsNullOrEmpty(from))
+ throw new ArgumentNullException(nameof(from));
+ if (string.IsNullOrEmpty(to))
+ throw new ArgumentNullException(nameof(to));
+
+ From = DateOnly.Parse(from);
+ To = DateOnly.Parse(to);
+ }
+
+ public static bool TryParse(string? value, IFormatProvider? provider, out DateRange? result)
+ {
+ if (string.IsNullOrEmpty(value) || value.Split('-').Length != 2)
+ {
+ result = default;
+ return false;
+ }
+
+ var range = value.Split('-');
+ result = new DateRange(range[0], range[1]);
+ return true;
+ }
+ }
+}
diff --git a/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Models/ErrorViewModel.cs b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Models/ErrorViewModel.cs
new file mode 100644
index 000000000000..9817f9658191
--- /dev/null
+++ b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Models/ErrorViewModel.cs
@@ -0,0 +1,9 @@
+namespace BindTryParseMVC.Models
+{
+ public class ErrorViewModel
+ {
+ public string? RequestId { get; set; }
+
+ public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
+ }
+}
\ No newline at end of file
diff --git a/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Models/WeatherForecast.cs b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Models/WeatherForecast.cs
new file mode 100644
index 000000000000..3bb0014da453
--- /dev/null
+++ b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Models/WeatherForecast.cs
@@ -0,0 +1,13 @@
+namespace BindTryParseMVC.Models
+{
+ public class WeatherForecast
+ {
+ public DateTime Date { get; set; }
+
+ public int TemperatureC { get; set; }
+
+ public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
+
+ public string? Summary { get; set; }
+ }
+}
diff --git a/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Models/WeatherForecastViewModel.cs b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Models/WeatherForecastViewModel.cs
new file mode 100644
index 000000000000..70e844c4034c
--- /dev/null
+++ b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Models/WeatherForecastViewModel.cs
@@ -0,0 +1,13 @@
+namespace BindTryParseMVC.Models
+{
+ public class WeatherForecastViewModel
+ {
+ public string? Date { get; set; }
+
+ public int TemperatureC { get; set; }
+
+ public int TemperatureF { get; set; }
+
+ public string? Summary { get; set; }
+ }
+}
diff --git a/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Program.cs b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Program.cs
new file mode 100644
index 000000000000..628d4f2953db
--- /dev/null
+++ b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Program.cs
@@ -0,0 +1,24 @@
+var builder = WebApplication.CreateBuilder(args);
+
+// Add services to the container.
+builder.Services.AddControllersWithViews();
+
+var app = builder.Build();
+
+// Configure the HTTP request pipeline.
+if (!app.Environment.IsDevelopment())
+{
+ app.UseExceptionHandler("/Home/Error");
+}
+
+app.UseStaticFiles();
+
+app.UseRouting();
+
+app.UseAuthorization();
+
+app.MapControllerRoute(
+ name: "default",
+ pattern: "{controller=Home}/{action=Index}/{id?}");
+
+app.Run();
diff --git a/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/Home/Index.cshtml b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/Home/Index.cshtml
new file mode 100644
index 000000000000..d2d19bdf9fb6
--- /dev/null
+++ b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/Home/Index.cshtml
@@ -0,0 +1,8 @@
+@{
+ ViewData["Title"] = "Home Page";
+}
+
+
diff --git a/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/Home/Privacy.cshtml b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/Home/Privacy.cshtml
new file mode 100644
index 000000000000..af4fb195a3c9
--- /dev/null
+++ b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/Home/Privacy.cshtml
@@ -0,0 +1,6 @@
+@{
+ ViewData["Title"] = "Privacy Policy";
+}
+@ViewData["Title"]
+
+Use this page to detail your site's privacy policy.
diff --git a/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/Shared/Error.cshtml b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/Shared/Error.cshtml
new file mode 100644
index 000000000000..a1e04783c67a
--- /dev/null
+++ b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/Shared/Error.cshtml
@@ -0,0 +1,25 @@
+@model ErrorViewModel
+@{
+ ViewData["Title"] = "Error";
+}
+
+Error.
+An error occurred while processing your request.
+
+@if (Model.ShowRequestId)
+{
+
+ Request ID: @Model.RequestId
+
+}
+
+Development Mode
+
+ Swapping to Development environment will display more detailed information about the error that occurred.
+
+
+ The Development environment shouldn't be enabled for deployed applications.
+ It can result in displaying sensitive information from exceptions to end users.
+ For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development
+ and restarting the app.
+
diff --git a/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/Shared/_Layout.cshtml b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/Shared/_Layout.cshtml
new file mode 100644
index 000000000000..6a375d9f29bd
--- /dev/null
+++ b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/Shared/_Layout.cshtml
@@ -0,0 +1,53 @@
+
+
+
+
+
+ @ViewData["Title"] - BindTryParseMVC
+
+
+
+
+
+
+
+
+ @RenderBody()
+
+
+
+
+
+
+
+
diff --git a/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/Shared/_Layout.cshtml.css b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/Shared/_Layout.cshtml.css
new file mode 100644
index 000000000000..08d7847058af
--- /dev/null
+++ b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/Shared/_Layout.cshtml.css
@@ -0,0 +1,49 @@
+/* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification
+for details on configuring this project to bundle and minify static web assets. */
+
+a.navbar-brand {
+ white-space: normal;
+ text-align: center;
+ word-break: break-all;
+}
+
+a {
+ color: #0077cc;
+}
+
+.btn-primary {
+ color: #fff;
+ background-color: #1b6ec2;
+ border-color: #1861ac;
+}
+
+.nav-pills .nav-link.active, .nav-pills .show > .nav-link {
+ color: #fff;
+ background-color: #1b6ec2;
+ border-color: #1861ac;
+}
+
+.border-top {
+ border-top: 1px solid #e5e5e5;
+}
+
+.border-bottom {
+ border-bottom: 1px solid #e5e5e5;
+}
+
+.box-shadow {
+ box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
+}
+
+button.accept-policy {
+ font-size: 1rem;
+ line-height: inherit;
+}
+
+.footer {
+ position: absolute;
+ bottom: 0;
+ width: 100%;
+ white-space: nowrap;
+ line-height: 60px;
+}
diff --git a/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/WeatherForecast/Index.cshtml b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/WeatherForecast/Index.cshtml
new file mode 100644
index 000000000000..db87b4a3c743
--- /dev/null
+++ b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/WeatherForecast/Index.cshtml
@@ -0,0 +1,43 @@
+@model IEnumerable
+@{
+ ViewData["Title"] = "Weather Forecasts";
+}
+
+Weather Forecasts
+
+
+
+
+
+ @Html.DisplayNameFor(model => model.Date)
+
+
+ @Html.DisplayNameFor(model => model.TemperatureC)
+
+
+ @Html.DisplayNameFor(model => model.TemperatureF)
+
+
+ @Html.DisplayNameFor(model => model.Summary)
+
+
+
+
+ @foreach (var item in Model) {
+
+
+ @Html.DisplayFor(modelItem => item.Date)
+
+
+ @Html.DisplayFor(modelItem => item.TemperatureC)
+
+
+ @Html.DisplayFor(modelItem => item.TemperatureF)
+
+
+ @Html.DisplayFor(modelItem => item.Summary)
+
+
+ }
+
+
diff --git a/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/WeatherForecast/Range.cshtml b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/WeatherForecast/Range.cshtml
new file mode 100644
index 000000000000..05becb200f26
--- /dev/null
+++ b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/WeatherForecast/Range.cshtml
@@ -0,0 +1,44 @@
+@model IEnumerable
+@{
+ ViewData["Title"] = "Weather Forecasts";
+}
+
+Weather Forecasts
+
+
+
+
+
+ @Html.DisplayNameFor(model => model.Date)
+
+
+ @Html.DisplayNameFor(model => model.TemperatureC)
+
+
+ @Html.DisplayNameFor(model => model.TemperatureF)
+
+
+ @Html.DisplayNameFor(model => model.Summary)
+
+
+
+
+ @foreach (var item in Model)
+ {
+
+
+ @Html.DisplayFor(modelItem => item.Date)
+
+
+ @Html.DisplayFor(modelItem => item.TemperatureC)
+
+
+ @Html.DisplayFor(modelItem => item.TemperatureF)
+
+
+ @Html.DisplayFor(modelItem => item.Summary)
+
+
+ }
+
+
diff --git a/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/_ViewImports.cshtml b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/_ViewImports.cshtml
new file mode 100644
index 000000000000..2797c59717f4
--- /dev/null
+++ b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/_ViewImports.cshtml
@@ -0,0 +1,3 @@
+@using BindTryParseMVC
+@using BindTryParseMVC.Models
+@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
diff --git a/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/_ViewStart.cshtml b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/_ViewStart.cshtml
new file mode 100644
index 000000000000..a5f10045db97
--- /dev/null
+++ b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/Views/_ViewStart.cshtml
@@ -0,0 +1,3 @@
+@{
+ Layout = "_Layout";
+}
diff --git a/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/appsettings.Development.json b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/appsettings.Development.json
new file mode 100644
index 000000000000..0c208ae9181e
--- /dev/null
+++ b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/appsettings.Development.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ }
+}
diff --git a/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/appsettings.json b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/appsettings.json
new file mode 100644
index 000000000000..10f68b8c8b4f
--- /dev/null
+++ b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/appsettings.json
@@ -0,0 +1,9 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ },
+ "AllowedHosts": "*"
+}
diff --git a/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/wwwroot/favicon.ico b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/wwwroot/favicon.ico
new file mode 100644
index 000000000000..63e859b476ef
Binary files /dev/null and b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/wwwroot/favicon.ico differ
diff --git a/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/wwwroot/site.css b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/wwwroot/site.css
new file mode 100644
index 000000000000..30ab421ce29d
--- /dev/null
+++ b/aspnetcore/mvc/controllers/bind-tryparse/7.0-samples/BindUsingTryParse/BindTryParseMVC/wwwroot/site.css
@@ -0,0 +1,18 @@
+html {
+ font-size: 14px;
+}
+
+@media (min-width: 768px) {
+ html {
+ font-size: 16px;
+ }
+}
+
+html {
+ position: relative;
+ min-height: 100%;
+}
+
+body {
+ margin-bottom: 60px;
+}