Learning Notes of ASP.NET Core MVC
Tags: learning, aspdotnet, mvc, core
Published: 2020-05-19 09:55:38

*(Original reference: https://zh.wikipedia.org/wiki/ASP.NET_Core_MVC)*

- Initial release on 27 June 2016.
- Latest release (ASP.NET Core MVC 1.1.2) on 16 Feb 2017.

# Routing (Convention-based routing)
``` cs
public void ConfigureServices(IServiceCollection services)
{
    // Register the ASP.NET Core MVC service to container.
    services.AddMvc();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    // ...
    // Configure with ASP.NET Core MVC
    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}
```

# Attribute routing
``` cs
[Route("api/[controller]")]
public class ProductsController : Controller
{
    [HttpGet("{id}")]
    public IActionResult GetProduct(int id)
    {
      ...
    }
}
```

# Controller
``` cs
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;

namespace WebApplication18.Controllers
{
    public class HomeController : Controller
    {
		public HomeController(IOptions<SampleWebSettings> settingsOptions) // injects dependence
		{
			_settings = settingsOptions.Value;
		}
		
		private readonly SampleWebSettings _settings;
		
        public IActionResult Index()
        {
			ViewData["Title"] = _settings.Title;
			ViewData["Updates"] = _settings.Updates;
			return View();
        }

        public IActionResult About()
        {
            ViewData["Message"] = "Your application description page.";

            return View();
        }

        public IActionResult Contact()
        {
            ViewData["Message"] = "Your contact page.";

            return View();
        }

        public IActionResult Error()
        {
            return View();
        }
    }
}
```

# Model Validation
``` cs
using System.ComponentModel.DataAnnotations;
public class LoginViewModel
{
    [Required]
    [EmailAddress]
    public string Email { get; set; }

    [Required]
    [DataType(DataType.Password)]
    public string Password { get; set; }

    [Display(Name = "Remember me?")]
    public bool RememberMe { get; set; }
}
```

# View Component
```cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;

namespace HelloMvc.Components
{
    [ViewComponent(Name = "AddNumber")]
    public class AddNumberComponent : ViewComponent
    {
        public async Task<IViewComponentResult> InvokeAsync(int Number1, int Number2)
        {
            int result = Number1 + Number2;
            ViewBag.N1 = Number1;
            ViewBag.N2 = Number2;
            return View(result);
        }
    }
}
```

# Tag Helper
``` cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.TagHelpers;

namespace HelloMvc.TagHelpers
{
    public class EmailTagHelper : TagHelper
    {
        private const string EmailDomain = "contoso.com";

        // Can be passed via <email mail-to="..." />. 
        // Pascal case gets translated into lower-kebab-case.
        public string MailTo { get; set; }

        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            output.TagName = "a";    // Replaces <email> with <a> tag

            var address = MailTo + "@" + EmailDomain;
            output.Attributes.SetAttribute("href", "mailto:" + address);
            output.Content.SetContent(address);
        }
    }
}
```

# Use Injection in View
``` cs
@using HelloMvc.Services;
@inject IDateTimeIndicator indicator 
<html>
    <body>
        ...
        <div>
            <ul>
                <li>@indicator.GetNowIndicator(new DateTime(2016, 5, 7, 0, 0, 0))</li>
                <li>@indicator.GetNowIndicator(new DateTime(2016, 5, 7, 0, 5, 0))</li>
                <li>@indicator.GetNowIndicator(new DateTime(2016, 5, 6, 0, 20, 0))</li>
                <li>@indicator.GetNowIndicator(new DateTime(2016, 5, 5, 0, 0, 0))</li>
            </ul>
        </div>
    </body>
</html>
```

# Optional Render Section
``` html
<environment include="Development">
    <div>The effective tag is: &lt;environment include="Development"&gt;</div>
</environment>
<environment exclude="Development">
    <div>The effective tag is: &lt;environment exclude="Development"&gt;</div>
</environment>
<environment include="Staging,Development,Staging_2">
    <div>
        The effective tag is:
        &lt;environment include="Staging,Development,Staging_2"&gt;
    </div>
</environment>
```

# Mapping Sequence of Model Binding
```
1. Form fields
2. The request body (For controllers that have the [ApiController] attribute.)
3. Route data
4. Query string parameters
5. Uploaded files
```

# Data Annotation
``` javascript
[Bind] | [BindProperty] | [BindProperty(Name = "Name123")]
[BindProperty(SupportsGet = true)] | [Key] | [DisplayName] | [Column] | [Required]
[DataType] | [Display] | [StringLength], [Range] | [EmailAddress]
[Range ] | [RegularExpression] | [RequestSizeLimit] | [HttpGet] | [HttpPost] 
[ApiController] | [ValidateAntiForgeryToken] | [FromForm] | [Route] | [ResponseCache]
[AllowAnonymous] | [ViewComponent]
```