:::: MENU ::::

Thursday, June 29, 2017

In version 5.x of Visual Studio, the File|New Project menu item enables you to create a brand-new project of any supported type. Let’s say you are interested in ASP.NET web application projects. Whether you want to work on a new classic ASP.NET MVC 5.x project, or an ASP.NET Core project, by default you have to choose between an empty project or sample web application project.
Oftentimes you end up with a lot of boilerplate code—that is, always the same—in an Empty project, and having to remove it from a sample web application project. In this article, I discuss the bare minimum code that every ASP.NET MVC application should have, to really save some valuable time and to help programmers – especially junior ones – to develop a more pragmatic mindset.
In my opinion, the best way to train junior developers is by teaching them how to do things right, and leaving them to their own devices in hands-on situations. A brand-new, tailor-made project template – approved by the team leaders – is an excellent tool to achieve this goal.
Here I illustrate my favorite one, also available for ASP.NET Core on GitHub here

Dealing with Globally Accessible Data

Many applications have some read-only data that must be globally accessible – for example, the application name, copyright information, functional and operational settings, and in general any information that’s preferable not to have hard-coded in the source files. If this information changes during use, then things can get quite complicated and a thread-safe cache object is desirable.
However any global read/write data tends to be application and business specific, so any attempt to generalize it might be superficial. Although if the data is read/write you might want to consider some flavors of a cache object, and some flavors of a distributed cache object if your application is deployable on web farms or subject to scale on multiple cloud servers.
Global read-only data is much easier to handle, even in a distributed environment. By read-only globally accessible data, I mean any constant data that you typically read from web.config and that can cause an application restart if modified.
So how would you store this read-only global data?
The easiest approach to take – and also the fastest-running – is using static variables. This is faster than reading them from an application cache. From a design perspective, you might want to shape up a class that gathers all possible pieces of data under the same roof, and then make a singleton instance of the class to use member variables, globally available to code. Although there’s some architectural changes, but the same approach can be used in ASP.NET Core. Let’s first see how to do this in classic ASP.NET MVC and then in ASP.NET Core.

Configuration Data in Classic ASP.NET MVC

In classic ASP.NET MVC, the start of an application is notified through the Application_Start event you handle in global.asax.
 public class StarterKitApplication : HttpApplication
{
    public static StarterKitSettings AppSettings { get; private set; }

    protected void Application_Start()
    {
        // Load configuration data
        AppSettings = StarterKitSettings.Initialize();

        // More things to do here
        ...
    }
    ...
}
In Application_Start, you can initialize the class to store all global configuration data. In the code snippet above, this class is called StarterKitSettings and it offers a factory method, named Initialize, to read data from whatever store they were kept, most likely the web.config file. Here’s an example that might work as a good starting point for the settings class of nearly any application.
 public class StarterKitSettings
{
    public string ApplicationTitle { get; private set; }

    public static StarterKitSettings Initialize()
    {
       var title = ConfigurationManager.AppSettings["starterkit:app-title"] 
                       ?? String.Empty;
       var settings = new StarterKitSettings
       {
            ApplicationTitle = String.Format("{0}", title)
       };
       return settings;
    }
}
All members of StarterKitSettings are read-only and initialized only once. An instance of the StarterKitSettings class is exposed out of the application main object as a static property. In this way, the data is globally available, and as fast as possible, because of the static nature of the container. It is still bound to the application via the HttpApplication object – the beating heart of ASP.NET applications. Consuming configuration data is as easy as using the following code:
 var title = StarterKitApplication.Settings.ApplicationTitle;
The settings are available from anywhere in the application because of the static attribute, but this doesn’t strictly mean that the data should always be consumed directly from the place it lives. Let’s consider the problem of setting the title of any views to the application name. The following code used in Razor layout view would certainly work:


   </span><span style="box-sizing: border-box;">
</span><span style="box-sizing: border-box;">     @StarterKitApplication.Settings.ApplicationTitle</span><span style="box-sizing: border-box;">
</span><span style="box-sizing: border-box;">   
...
However, it is probably cleaner from the design perspective if you just package the title as read from the settings into a view model object passed to the view. In this way, the desired data is injected where it is really useful. I’ll expand on the view model example later on in the article, when touching on the relationships between controllers and views. For the time being, I’d say that this approach has been taken one step further and, more importantly, engineered as built-in infrastructure in ASP.NET Core.

Configuration Data in ASP.NET Core (done editing)

ASP.NET Core allows you to read configuration data through a variety of providers and from a variety of sources, most notably JSON files. (There’s no web.config file required in ASP.NET Core). The framework provides an easy way to map the content of the configuration JSON file to your class. Let’s assume the following JSON settings:
 {
  "ConnectionStrings": {
    "YourDatabase": "Server=(local);..."
  },
  "Globals": {
    "Title": "Your application title"
  }
}
The code below loads it into the memory of the application:
public IConfigurationRoot Configuration { get; }
public Startup(IHostingEnvironment env) 
{
    var builder = new ConfigurationBuilder() 
         .SetBasePath(env.ContentRootPath) 
         .AddJsonFile("StarterKitSettings.json"); 

    // This is a container defined on the Startup class as a property
    Configuration = builder.Build(); 
}
The code runs in the constructor of the Startup class and populates an IConfigurationRoot object with the entire list of settings. But how can you consume that data? Here’s where the Options service of ASP.NET Core fits in:
 public void ConfigureServices(IServiceCollection services)
{
      services.AddOptions();
      services.Configure(Configuration.GetSection("Globals"));
}
The Options service has the ability to load an instance of the specified type—GlobalConfig—in the code snippet with any properties in the given section of the configuration tree that matches member names. In a way, it is as if settings were model-bound to an instance of the GlobalConfig class. Say the class looks like the following:
 public class GlobalConfig 
{ 
    public string Title { get; set; } 
}
The value of the Title property in the Globals section of the JSON file is copied into the matching property of the GlobalConfig class. In the end, there’s an instance of a user-defined class that holds all the configuration data. However, this class is NOT globally accessible from any place in the code. To be usable, it must be explicitly injected wherever there’s the need for it. The ASP.NET Core Dependency Injection (DI) infrastructure provides an easy and effective way to do just this. Here’s how you can inject the instance of GlobalConfig in a controller.
 public class HomeController : Controller
{
    private GlobalConfig Configuration { get; }

    public IActionResult Index(IOptions config)
    {
        Configuration = config.Value;
    }
    ...
}
The configured instance of GlobalConfig is treated as a singleton by the DI infrastructure so that the overall pattern is very close to the one outlined for classic ASP.NET MVC.

Dealing with Application’s Errors

Another feature that nearly any application needs to have properly addressed – even if it’s only a prototype – is error handling. If you read through the ASP.NET MVC documentation, you’ll see there are many ways to do this. However, my take on it is that you only need to decide whether the error (or rather, the exception in the code) is something you want to try to prevent or just handle, if and when it happens.
If you are aware that your code is performing a possibly problematic operation, then the best you can do is wrapping that code in a try/catch block and recover nicely if something goes wrong. If you used a try/catch block, then from the perspective of the caller of the failing code nothing bad has happened. The caller receives a response, except that the response could be empty or incomplete. All other scenarios are better handled through a global error handling strategy.
ASP.NET MVC offers an attribute like HandleError and action filters specialized in dealing with exceptions, but all those things don’t address all possible exceptions an application can run into. In particular, route exceptions and model binding exceptions are not covered. That’s why it is preferred to only go with an application level error handler – and one that’s done in a smart way, as the one in ASP.NET Core.

Error Handling Strategy in Classic ASP.NET MVC

In ASP.NET, any exceptions not trapped locally by a try/catch block bubbles up and turns into a yellow-page-of-death unless an Application_Error handler is defined in global.asax.
 protected void Application_Error(object sender, EventArgs e)
{
   var exception = Server.GetLastError();

   var httpContext = ((HttpApplication)sender).Context;
   httpContext.Response.Clear();
   httpContext.ClearError();
   InvokeErrorAction(httpContext, exception);
}
There are two main things you want to do from within the error handler. First, grab the last error that occurred. In classic ASP.NET the information is returned by the GetLastError method on the Server object (this is different in ASP.NET Core). Next, you have to display—in some way—the error view. Sounds easy? Well, not exactly. If you just redirect to an error page you lose the information about the exception, unless you find a way to package it up with the redirect operation. Losing the exception details might not be a problem if it is OK for you to just show a static HTML page – for security reasons this is sometimes just the way to go. However, if you want to enable some debug mode on production code you have no way to get to know exactly what went wrong.
You can’t serve HTML from the handler either. Creating yourself an instance of some Error controller class and invoking a view from there is not an option, either. You can call the controller but rendering the view is a different story. This solution is a bit tricky, but it works: 
 private static void InvokeErrorAction(HttpContext httpContext, Exception exception)
{
     var routeData = new RouteData();
     routeData.Values["controller"] = "error";
     routeData.Values["action"] = "index";
     routeData.Values["exception"] = exception;
     using (var controller = new ErrorController())
     {
       ((IController)controller).Execute(
            new RequestContext(new HttpContextWrapper(httpContext), routeData));
     }
}
Essentially, the code prepares an internal request for the action invoker to consider, and makes it look as if it came from the outside. The request takes the form of the URL error/index with exception data packaged in the route data container.
The Index method on the ErrorController receives the exception via model binding and goes through its own workflow to figure out which view to serve and which data to pass. 
 public ActionResult Index(Exception exception)
{
    ...
}
With this safety net installed from anywhere in your code, you can just throw an exception if something is wrong and you don’t want to even try to recover. The exception goes unhandled and results in a nice error page displayed that at the very minimum may contain the message associated with the exception.

Error Handling Strategy in ASP.NET MVC Core

Interestingly, ASP.NET Core takes a similar approach when it comes to production-level error handling and the tricky code shown above (or rather its .NET Core equivalent) is baked in the framework and available through a simple call. In ASP.NET Core, nothing – not even error pages – come out of the box and every functionality must be explicitly enabled. Here’s a common pattern for dealing with error handling in ASP.NET Core: 
 public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
   if (env.IsDevelopment())
   {
       app.UseDeveloperExceptionPage();
       app.UseStatusCodePagesWithReExecute("/Error/Index/{0}");
   }
   else
   {
       app.UseExceptionHandler("~/Home/Error");
       app.UseStatusCodePagesWithReExecute("/Error/Index/{0}");
   }
   ...
}
If the application is running in development mode, you instruct the runtime to serve the canonical error page, which is full of detailed information about what has happened, including the stacktrace. Otherwise, the specified error handler is invoked as a URL. The URL is processed within the runtime as if it were a request coming from the outside. Special attention is also put on particular status codes, such as 404. In this case, if it’s not an internal error, the status code is passed on the URL and can be captured by the controller method via model binding. In ASP.NET Core, the error method doesn’t receive information about the exception but has to work its way to retrieve it. 
 var lastException = HttpContext.Features.Get().Error;
The object retrieved exposes the last occurred exception via the Error property of the IExceptionHandlerFeature object. The information in the exception can then be used to prepare the view model to render back to the user.

Application Services and Controllers

ASP.NET MVC forces you to create controller classes to organize the functionalities of an application, and this seems ideal to achieve due to separation concerns. The reality is a bit different. Further layering is necessary and it is entirely up to you. An easy and effective way to achieve true separation of concerns in ASP.NET MVC is using application service classes from within the controller. These classes form the “application layer” of the solution and are responsible for the implementation of use-cases. The recommended strategy is based on the following points:
  • Any action the controller must take is delegated to a controller-specific, application service class. This class is not expected to be reusable and largely depends on the frontend that called it. It comes as no surprise that you may end up with different application services for mobile application calls and web application calls.
  • Methods on the application service class accept data as it comes from the model binder. Whatever the controller gets, it passes down the stack to the application service class. Only if strictly necessary the controller will make changes to the received data before passing it down to the service class.
  • Methods on the application service class return data packaged in a view model object ready to be handed to the view engine for rendering out the HTML view. (This is required only if the controller is expected to return HTML.)
In classic ASP.NET MVC, you can define the application service as below. 
 public class HomeController : Controller
{
    private HomeService _homeService = new HomeService();

    public ActionResult Index(...)
    {
        var model = _homeService.GetIndexViewModel(...);
        return View(model);
    }
}
Needless to say, you can extract an interface from the application service class and program the controller against it rather than having it work against a concrete implementation. You may use poor-man dependency injection for this purpose: 
 public class HomeController : Controller
{
    private IHomeService _homeService; 
    public HomeController(IHomeService service)
    { 
       _homeService = service;
    }
    public HomeController() : this(new HomeService())
    { 
       _homeService = service;
    }

    public ActionResult Index(...)
    {
        var model = _homeService.GetIndexViewModel(...);
        return View(model);
    }
}
In addition, you can also use the appropriate IoC library to resolve the controller instance. This is fully supported by ASP.NET MVC and requires you to set a custom, IoC-based controller factory.
Nicely enough, this same pattern comes out of the box in ASP.NET Core where an internal DI system is in place. All you have to do in ASP.NET Core is register your application service classes with the DI system and just inject instances wherever you need them to be.
 public class HomeController : Controller
{
   private readonly HomeService _homeService;

   public HomeController(IHomeService service)
   {
      _homeService = service;
   }

   public IActionResult Index()
   {
       var model = _homeService.GetHomeViewModel();
       return View(model);
   }
}
To make sure the dependency is correctly resolved you need to let the DI system know about the injectable type—the IHomeService interface. Here’s the code you need to have in the configuration of the ASP.NET Core application: 
 public void ConfigureServices(IServiceCollection services)
{
   services.AddTransient();
   ...
}
The net effect of the code above is that any new instance of the controller class will receive a fresh new instance of the HomeService class.

Controllers, Views and View Models

There are many ways for a controller method to pass data on to a view. You can use the ViewData dictionary, the ViewBag dynamic object, or view model classes. I’m a strong believer in view model classes. However conceptually, a view model class is quite different from the entity class you might use via Entity Framework to read and write data from a database.
A view model class defines the amount of data being passed to a particular view in the shape and form that the view needs. The view is essentially passive in the sense that either it doesn’t contain code at all, or it just contains some specific pieces of rendering and formatting logic. A view model class may sometimes reference an entity object but I haven’t yet found a realistic application that populates its views only through an entity object.  
View model classes should be grouped by layout. Any layout view you use in the application should have its own base view model class from which all view model classes derive to fill out views based on the layout. Here’s a sample view model base class for a layout: 
 public class ViewModelBase
{
    public ViewModelBase(string title = "")
    {
        Title = title;
        ErrorMessage = "";
        StatusCode = 0;
    }

    public string Title { get; set; }
    public string ErrorMessage { get; set; }
    public int StatusCode { get; set; }
}
The layout file declares its model to be of the ViewModelBase type and all views based on the layout will have a view model class that just inherits from ViewModelBase. 
 @model ViewModelBase
View model classes can be conveniently grouped under a ViewModels folder in the project, with each going into a subfolder specific of the layout it refers to. You may think this organization is a bit too complex for simple things. However I believe disorder and lack of organization make things more complex than they really are. Far too often I have met developers who justified limited use of view models with the fact that they were in a hurry and the approach was time-consuming. They were all developers who then had problems to fix down the road.
The approach described here based on view models works well both in classic ASP.NET MVC and in ASP.NET Core.

Summary

While each application is different by nature, as long as they are based on a given framework, they all should look the same when it comes to fundamental features and overall design. Regarding ASP.NET MVC, the way you organize controllers and views and ancillary aspects – such as configuration and error handling – should be common to all applications because in the end, it’s just infrastructure.
Every team probably has its own ideal way of coding common aspects of their applications. This article only presented my personal take for both ASP.NET MVC and ASP.NET Core. However, for me it was a nice finding when I realized that most of my personal best practices of ASP.NET MVC are now consolidated and engineered straight in ASP.NET Core. You will find a full implementation of the ASP.NET MVC template discussed in the article for ASP.NET Core at http://github.com/despos/youcore. I’m looking forward to your feedback.

Thursday, June 22, 2017


New free product – ApexSQL Compare: Compare SQL scripts and objects

In the last newsletter we announced the release of a new free product, ApexSQL Plan, a SQL Server query plan viewer and analysis tool.
This newsletter we are announcing the release of another new, free tool; ApexSQL Compare, a tool to compare SQL scripts and objects.

Here is a full list of the tool’s features:
  • Compare SQL Server objects directly from SSMS and Visual Studio
  • File and folder comparison
  • Two-way compare and merge
  • Full support for Command Line Interface
  • Compare models: Block, Line, Character
  • Syntax highlighting
  • Ignore comparison options: Ansi options, Authorization, Collation, Comments, Constraint names, Filegroups, Indexes, Lock escalation, Permissions, With encryption
  • Integrated editor
  • Support for Windows Explorer integration
  • Exporting comparison results into HTML
In addition to the ApexSQL Compare product page, you can walk through all of the features of the tool via the article ApexSQL Compare screen shot tour.

Free community editions
Many people are familiar with our free tools, but fewer know about all of the 100% free editions of other popular, non free tools. The free editions offer support for Azure SQL database, SQL Express and Amazon RDS. Click here to see all of our free tool editions.
If so, we offer free keys for ApexSQL MonitorApexSQL Backup and ApexSQL Source Control. We’d welcome you to join the many others who have taken advantage of a great, risk free opportunity to obtain real license to our products.

Monday, June 19, 2017

Websites often need to generate SEO friendly URLs. In Razor Pages the URL is tied to a physical .cshtml file. This default mapping between the URL and physical file makes it difficult for Razor Pages websites to generate SEO friendly URLs.
Last few days the ASP.NET team add a small & great feature to create friendly URLs in Razor Pages. In this short blog post I will show you how to configure the routes in the Razor Pages to create friendly URLs.
Razor Pages out-of-the-box let use access your pages from their locations, So the URLs http://{your-domain}/Post/Index and http://{your-domain}/Post will be mapped to the file /Pages/Post/Index.cshtml. (Index file name is optional).
But what if we need URLs like this http://{your-domain}/Post/2017/5/29?!! You can decorate your razor page using @page "{year}/{month}/{day}" to make this happen :)
As we have seen Razor Pages is already give us the controller to generate a simple & clean URLs, nothing but there are some case may you need much more than that.
Assume our previous file name located in /Pages/Post/Archive.cshtml and we wanna apply the same route http://{your-domain}/Post/2017/5/29, here where the previous bits was limited, but not anymore :)
Now you easily achieve that with the new extension method named AddPageRoute as the following:
services.AddMvc()
    .AddRazorPagesOptions(options =>
    {
        options.RootDirectory = "/Pages";
        options.AddPageRoute("/Post/Archive.cshtml", "Post/{year}/{month}/{day}");
    });
Also you can used an optional parameter if you do so
options.AddPageRoute("/Categories/Laptops.cshtml", "Laptops/{id?}");
The extension is not complicated as we think, basically it provides a simple runtime configuration of routes.
public static RazorPagesOptions AddPageRoute(this RazorPagesOptions options, string pageName, string route)
{
    if (options == null)
    {
        throw new ArgumentNullException(nameof(options));
    }

    if (string.IsNullOrEmpty(pageName))
    {
        throw new ArgumentException(nameof(pageName));
    }

    if (string.IsNullOrEmpty(route))
    {
        throw new ArgumentException(nameof(route));
    }

    options.Conventions.Add(new PageConvention(pageName, model =>
    {
        foreach (var selector in model.Selectors)
        {
            selector.AttributeRouteModel.SuppressLinkGeneration = true;
        }

        model.Selectors.Add(new SelectorModel
        {
            AttributeRouteModel = new AttributeRouteModel
            {
                Template = route,
            }
        });
    }));

    return options;
}
Now you can create your friendly URLs easily in the Razor Pages :)
Happy Coding ..
Hint: The thing I notice in the new API other than routing in ASP.NET Webforms or MVC is inverting the order of parameters, in other words the route appear before the physical page, which is may confusing little bit.
Caching is the process of storing frequently used data, this data is costly to generate for reuse. Usually this data are stored in memory because retrieving data from memory is very fast and more efficient than retrieving the data from other locations such as database.
ASP.NET Core provide us both in-memory and distributed caching. Caching repository has three different caching storage, In-Memory, Redis and SQL Server.

Cache Dependencies

Dependencies allow us to invalidate a particular item within the Cache based on file, key changes or at a fixed time.
In the previous version of ASP.NET there are three types of dependencies supported:
  • File based dependency
  • Key based dependency
  • Time based dependency
In ASP.NET Core we can invalidate a cache item based on time using the MemoryCacheEntryOptions class, nothing but the other cache dependencies are not there!! but that doesn't mean they are impossible to implement. So in this blog post I will show you how we can implement a file based dependency.
First of all we need to create the FileCacheDependency class:
public class FileCacheDependency
{
    public FileCacheDependency(string filename)
    {
        FileName = filename;
    }

    public string FileName { get; }
}
This is simple enough to store the file name that when need to monitor to invalidate the cache items, based on its change, second we need to add an extension method to add file based dependency.
public static class MemoryCacheExtensions
{
    public static void Set(this IMemoryCache cache, string key, TItem value, FileCacheDependency dependency)
    {
        var fileInfo = new FileInfo(dependency.FileName);
        var fileProvider = new PhysicalFileProvider(fileInfo.DirectoryName);
        cache.Set(key, value, new MemoryCacheEntryOptions()
                            .AddExpirationToken(fileProvider.Watch(fileInfo.Name)));

    }
}
Simply I used PhysicalFileProvider to monitor the give file, thanks Watch() method :)
Then we can use it as the following:
var cache = new MemoryCache(new MemoryCacheOptions());
var dependency = new FileCacheDependency("FilePath");

cache.Set("cacheKey", "cachValue", dependency);
Similarly we can create TimeCacheDependency class:
public enum CacheItemPolicy
{
    AbsoluteExpiration,
    SlidingExpiration
}

public class TimeCacheDependency
{
    public TimeCacheDependency(TimeSpan time, CacheItemPolicy policy = CacheItemPolicy.AbsoluteExpiration)
    {
        Time = time;
    }

    public TimeSpan Time { get; }

    public CacheItemPolicy Policy { get; }
}
Finally add an extension method to MemoryCacheExtensions class
public static void Set(this IMemoryCache cache, string key, TItem value, TimeCacheDependency dependency)
{
    var options = new MemoryCacheEntryOptions();

    if (dependency.Policy == CacheItemPolicy.AbsoluteExpiration)
    {
        options.SetAbsoluteExpiration(dependency.Time);
    }
    else
    {
        options.SetSlidingExpiration(dependency.Time);
    }
    cache.Set(key, value, options);
}
That's it!!  also you can implement the key based dependency if it's required.

Thursday, June 15, 2017

Currently there are many ways to extend or to organize your Razor views in ASP.NET Core MVC. Let us start with the very basics and let us go to the more complex ways. If your are familiar with previous ASP.NET MVC Frameworks you'll definitely know most of this. But almost all of that "old" stuff is still possible in ASP.NET Core MVC. Some of them listed below shouldn't be used anymore and some of that stuff is completely new in ASP.NET Core MVC. With this post I'm going to try to write down all options to organize and extend MVC Views.

#1: Typed Views

A very basic View without any dynamic stuff is not very common. Even in Visual Studio it is not really visible, because you usually get a running per-configured web, if you start a new project. It is simply a HTML page with *.cshtml as the file extension. You can use Razor syntax, HtmlHelpers and UrlHelpers here to make your HTML code more dynamic. You can use the ViewBag Object or the ViewData collection to pass Data from your Controller action to your View. But this data are not typed and you don't really know whether the data exist in this list or what type the data are.
To use typed date in your view, you need to define a model to use in your view.
@model ExtendViews.ViewModels.AboutModel


@Model.FullName
This is pretty common for ASP.NET MVC developers, even the next topic is a known and pretty basic way:

#2: Layouts

Almost equal to the MasterPages in ASP.NET WebForms, there is a central way to define the basic layout of your Razor view. This is done with a _Layout.cshtml, which is located in the Views\Shared\ folder. This file usually contains the HTML header, body tags and all the things which are shared between all of your Views.
You can also nest layout views to have a basic layout and different per area on your web site. To use a Layout you need to call it by its name without the file extension:
@{
    Layout = "_Layout";
} 
This call needs to be in the first lines of your views. But you don't need to define the Layout in every view, if you already have defined a default Layout. This is already done, if you start a new ASP.NET Core project in Visual Studio. There is a _ViewStart.cshtml in the Views folder where the default Layout is set-up.
Inside the _Layout.cshtml there is a mothod callRenderBody(), which calls the rendering ov the current view at this location:
@RenderBody()
Place this method call at that location where where your view should be rendered.

#3: Sections

Sometimes you need to create HTML code in your view, which should be rendered on another location than the main parts of the view. This can be done with Sections. Sections are named areas in your view and usually used to put JavaScripts from your views in to a separate location, e.g. at the end of the page.
To define a section for some JavaScripts just call the Section you want to render somewhere in the _Layout.cshtml:
@RenderSection("scripts", required: false)
With the flag required you are able to define whether the sections is needed or optional. Now you can use the section in your view:
@section scripts
{
    <script>
        $(function() {
            // some more js code here;
        });
    </script>
}
If you use nested layouts, you probably need to nest this areas. This means you need to call the RenderSection() inside a Section:
@section scripts
{
 @RenderSection("scripts", required: false)
}

#4: PartialViews

To reuse parts of your views you can extract this parts and put it into a new Razor view. This view doesn't have an own Action in the controller. This thing is called a PartialView. A PartialView should be placed in the same folder as the View which uses the PartialView or even in the Views\Shared\ folder.
A PartialView can also be a typed view (but don't have to) to get data from the parent View:
@model IEnumerable<UserModel>
@if (Model.Any())
{
    <ul>
        @foreach (var user in Model)
        {
            <li>@user.FullName</li>
        }
    </ul>
}
This PartialView needs a list of users from the parent view
@{ await Html.RenderPartialAsync("Users", Model.Users);}
If your PartialView doesn't have a model defined, you don't need to pass the second parameter.

#5: ViewComponents

This is new in ASP.NET Core
Sometimes you need to have something like PartialView, but with some more logic behind. In the past there was a way to use ChildActions to render the results of controller actions into a view. In ASP.NET Core MVC there is a new way (which I already showed in this post about ViewCmponents) with ViewComponents. This are a kind of mini MVC inside MVC, which means they have an own Controller, with an own single action and a view. This ViewComponents are completely independent from your current view, but also can get values passed in from your view.
To render a ViewComponent you need to call it like this:
@Component.Invoke("Top10Articles");
Please have a look at my previews post about ViewComponent to learn how to create your own.

#6: HtmlHelpers

You can extend the Razor syntax by creating your own extension methods on the HtmlHelper class:
public static class HtmlHelperExtensions
{
    public static HtmlString MyOwnHtmlHelper(this HtmlHelper helper, string message)
    {
        return new HtmlString($"<span>{message}<span>");
    }
}
This is pretty useful to create reusable parts of your view, which includes some more logic than a PartialView. But even better than HtmlHelper extensions are the new TagHelpers. HtmlHelpers are still a valid option to extend your Views.

#7: TagHelper

This is pretty new in ASP.NET Core.
This little helpers are extensions of your view, which are looking like real HTML tags. In ASP.NET Core MVC you should use this TagHelpers instead of the HtmlHelpers because they are more cleaner and easier to use. Another huge benefit is Dependency Injection, which can't be used with the HtmlHelpers, because the static context of extension methods. TagHelpers are common classes where we can easily inject services via the constructor.
A pretty simple example on how a TagHelper could look like:
[TargetElement("hi")] 
public class HelloTagHelper : TagHelper 
{ 
    public override void Process(TagHelperContext context, TagHelperOutput output) 
    { 
        output.TagName = "p"; 
        output.Attributes.Add("id", context.UniqueId); 

        output.PreContent.SetContent("Hello "); 
        output.PostContent.SetContent(string.Format(", time is now: {0}",  
                DateTime.Now.ToString("HH:mm"))); 
    } 
}
This guy defines a HTML Tag called "hi" and renders a p-tag and the contents and the current Time.
Usage:
<hi>John Smith</hi>
Result:
<p>Hello John Smith, time is now: 18:55</p>
ASP.NET Core MVC provides many built in TagHelpers to replace the most used HtmlHelpers. E. g. the ActionLink can now replaced with an Anchor TagHelper:
@Html.ActionLink(“About me”, “About”, “Home”)
The new TagHelper to create a link to an action looks like this:
<a asp-controller=”Home” asp-action=”About”>About me</a>
The result in both cases is a clean a-Tag with the URL to the about page:
<a href=”/Home/About”>About me</a>
As you can see the TagHelpers feel more than HTML and they are easier to use and more readable inside the Views.

#8: Dependency Injection

This is new in ASP.NET Core too.
The biggest improvement to extend your view is dependency injection. Yes, you are able to use DI in your View. Does this really make sense? Doesn't it mess up my view and doesn't it completely break with the MVC pattern? (Questions like this are currently asked on StackOverflow and reddit)
I think, no. Sure, you need be careful and you should only use it, if it is really needed. This could be a valid scenario: If you create a form to edit a user profile, where the user can add its job position, the country where he lives, his city, and so on. I would prefer not to pass the job positions, the country and the cities from the action to the view. I would prefer only to pass the user profile itself and I only want to handle the user profile in the action. This is why it is pretty useful in this case to inject the services which gives me this look-up data. The action and the ViewModel keeps clean and easy to maintain.
Just register your specific service in the method ConfigureServices in the Startup.csand use one line of code to inject it into your view:
@inject DiViews.Services.ICountryService CountryService;
No you are able to use the ContryService in your View to fill a SelectBox with list of countries.
I wrote more about Dependency Injection in ASP.NET Core this posts).

#9: Functions

I never used functions in real ASP.NET MVC projects. I only used it with a the razor engine in an Umbraco web. Anyway, this is another possibility to extend your views a little bit. Maybe you have some a more complex view logic, in this case you can write C# methods in an functions area inside your view:
@functions
{
    public string ReverseString(string input)
    {
        return String.Join("", input.Reverse());
    }
}

#10: Global view configuration

Last but not least, there is a separate razor file you can use to configure some things globally. Use the _ViewImports.cshtml to configure usings, dependency injections and many more which should be used in all Views.

Conclusion

There are many ways to extend our views. some of them are known from previous MVC versions and some of them are new. Some of them shouldn't be used anymore because there are new or better ways. But you are free to decide which feature you want to use to get your problems solved.
Did I forget something? Please drop me a comment, to tell me what I need to add. If you miss something what you used in previous MVC versions, this is possibly not longer working in ASP.NET Core MVC (e.g. ChildActions). Anyway, feel free to ask me :)