Learning ASP.NET Core MVC 1.1

ASP.NET Strengths

1. Visual Studio IDE

2. Template/ Library Diversity

3. Community

Comes with JQuery, Bootstrap, Knockout (DOM)


Building Blocks covered:
1. Creating a Core MVC Application
2. Securing the application
3. Interacting with database
4. Dependency injection and MVC pattern
5. Dynamic views
6. Expose data as web API
7. Partial rendering with AJAX


ASP.NET Core Application Stack


Because the ASP.NET Core framework is being launched alongside a brand new version of the full .NET framework called .NET Core. .NET Core is a lightweight, fast and modular version of the full .NET framework, fully rewritten from the ground up. I'll talk a little bit more about .NET Core in later videos, but what you need to know right now is that when it comes time to choose the .NET runtime to run your ASP.NET Core application on, you've got a choice between the full .NET framework or the new slimmed down .NET Core.

Your application will work on either one. Perhaps more importantly than how lightweight the .NET Core framework is, is the fact that it's cross-platform. Unlike the full .NET framework, which only runs on Windows, which meant that previous versions of .NET were pretty tightly coupled to both Windows and the IIS web server that runs on Windows. However, ASP.NET Core also takes full advantage of .Net Core support for cross-platform compatibility and this opens up a whole new world of options and opportunities for developers.

Create a project: ASP.NET Core 1.1 Empty Template

Responding to HTTP Requests

Concept of Middleware:

A web application is nothing more than just a bunch of functions that get registered to handle requests in a certain order. Then, when a request comes in ASP.NET simply creates a new instance of this pipeline and populates it with these functions.

Then calls each of them, one after another, giving each one an opportunity to modify the request or perform some action before the response is sent back to the user. The interesting thing about this process is that none of the functions know anything about each other. They just execute their own logic and that's it. Following this approach often leads to creating middleware functions that are general enough that they may be reused in many different applications.

This is happening because our default application has one single piece of middleware registered. And that is this app.Run method. Because it's the only functionality registered, and it has no conditional logic to keep it from executing, it and it alone gets executed for every single request. The app.Run method is actually a special way of registering logic that's the final piece of logic to execute to for every request. In other words, it says to execute this logic, and then immediately return the response to the user.


Realistically, you'll rarely, if ever, use the app.Run method to register middleware. So, let's shift our focus to the more effective way to register request handling logic. The app.Use method. Like the app.Run method, the app.Use method also takes a function to hold the request processing logic.


, this function has two parameters instead of just one. The first parameter represents the request, just like with app.Run. And the second parameter represents the next middleware function registered in the pipeline. This is a simple, but powerful way for every middleware component to have full control over when and how the next component in the pipeline is executed. Now that I've modified this first app.Run method call to use app.Use instead, when I refresh the page, both functions will execute and both messages should be rendered to the user.



app.Use(async (context, next) =>

            {
                if(context.Request.Path.Value.StartsWith("/hello"))
                {
                    await context.Response.WriteAsync("Conditional logic here");      
                }
                await context.Response.WriteAsync("Hello ASP>NET Core");
                await next();

            });


However, to make this work, in order to tell ASP.NET Core to continue processing the request with the next middleware registered, we'll need to add a call to the next function somewhere in this function to tell ASP.NET Core when that next task should execute. Now if I save this file, and go back and refresh the browser, we should see both messages being rendered. Now what if I only want to run this logic when the URL starts with a certain path? That's simple.


Just add an if statement around the right async method. Here I'll write one that checks for a URL with the pattern /hello. If the URL matches, the content gets rendered out. Otherwise the request is not modified and processing just continues on to the next function that is registered to handle it. In this video, I introduced the concept of middleware, and even showed a few low-level examples of how to modify a response by registering your own custom middleware into the ASP.NET Core pipeline.

Leverage external dependencies -  

Unlike previous versions of the ASP.NET framework where the entire framework was installed on your machine and automatically available to you in any of your applications, in an ASP.NET Core project, you need to explicitly opt in to any libraries you'd like to use including most of the ASP.NET Core libraries themselves. In this video, I'll show you how to link not only to those missing ASP.NET Core libraries, but also thousands of other community supplied libraries that you can use to help you build your applications.


In order to do that, we'll use the NuGet Package Manager, which has been a helpful tool that's been available in Visual Studio for many years, but has finally become an integral part of ASP.NET Core development. In order to get to the NuGet Package Manager, simply right-click on the project and choose Manage NuGet Packages. When the NuGet Package Manager UI comes up, you'll be on the Installed tab, which lists all of the packages that the Visual Studio template has already installed for us containing the libraries that our application depends on.

Using ASP.NET Core middleware to start responding to requests with static content such as HTML pages and CSS

In this video, I'm going to show you how to use ASP.NET Core middleware to start responding to requests with static content such as HTML pages and CSS. Take a look at the Artifacts folder in chapter one of your exercise files and look in the site folder. This folder contains all of the static HTML and CSS for the Explore California site that I showed earlier. I'll use this static content as the first thing that we host in this new ASP.NET Core application I'm building.
In order to host these files, the first thing I have to do is drop them into the wwwroot folder underneath my project. I'll do that by copying the files and then pasting them into the wwwroot folder in my project. The wwwroot folder is kind of a safeguard. Unlike previous versions of ASP.NET, where you had to put all of your application code and static files all into one application folder, potentially making them all viewable to the outside world, ASP.NET Core actually encourages you to separate the two types of files.

Throughout the rest of this course, we'll continue to put all of our application code and development artifacts into the root of our project, but any static files that we want to expose to the world, we will place in this wwwroot folder so that ASP.NET Core can tell the two types apart. If I try to switch to the browser and demonstrate these static files right now, the site will actually respond with those canned responses that we've been playing with in the last few videos. Since I've already explained the concept of middleware, I think we can just go ahead and delete these responses.

To fix this, and to start serving the static content that I just pasted, simply go back into the Startup class and uncomment the line app.UseFileServer(); This call will register that static files middleware component which tells ASP.NET Core to try to map any unhandled request to a file in the wwwroot folder, and if that file exists, go ahead and serve it. This mapping even includes default pages, such as an index.html file, which is why I see the contents of my index.html file when I navigate to the root of my site, as I've shown here.

Error Handling

To demonstrate an error, I'll just add a bit of code to the configure method in the startup class that throws an exception when the URL contains the word: invalid. Then I'll run the site and navigate to a URL like /invalid.
Here I'm greeted by an incredibly helpful error message containing all kinds of useful information to help me figure out what went wrong with my application. At the top, it shows me the error message and then lower down I can click on various sections of the stack trace and, if it's my code, I can actually see that code right there in my browser. In addition to the stack trace information, the page also has several other tabs that allow me to see other details of my request, including the query string information, the details of any cookies included in the request, and the headers that were sent from my browser to the server.
You're probably wondering where this great page came from? As with everything in an ASP.NET Core application, this behavior needed to be explicitly added to the pipeline. That happened in this call to app.UseDeveloperExceptionPage that Microsoft included for us in the default template on line 28. Now, this diagnostics information is great for us as developers when we're developing our application, but it's generally not a good idea to display this kind of error page to actual users.
Not only is it a security risk, it's just a plain bad experience. So, for better, more production-worthy error pages, this diagnostics library actually gives us one more really helpful middleware function and that is: app.UseExceptionHandler. This middleware listens for any exceptions that may occur during the course of a request, then logs the error and redirects the request to a friendly error page that's more helpful for a user of the site who doesn't really care about the stack trace in which the error occurred.
Here, I've told the error handler to display the static page /error.html. In order for this to work, we'll need an html file with that name in the www root directory. Luckily, the static content that we copied earlier already contained this error.html file. With this in place, I can switch back to the browser and view the error page again but I'm still going to see the diagnostic page from before. That's because the UseDeveloperExceptionsPage middleware is registered after the UseExceptionsHandler middleware that I've just added, which means that it's going to handle the request first.
When I'm in development mode, that's actually exactly what I want to happen. But, not in any other environment. This is exactly why this call is wrapped in the conditional statement: if (env.IsDevelopment()) on line 28. In order to see the production error page, I'll first need to disable the development environment that this site is currently running in. To do that, I'll go to the Debug tab in the project's build properties.
In here, I'll look for the ASPNETCORE_ENVIRONMENT variable that Visual Studio set to Development for me, which tells ASPNETCORE to enable development mode. If I remove this variable, or set it to another value, my site will no longer be running in development mode, and the developer exception page middleware will not be registered. I can then save the update value and switch back to the browser, and refresh the page to try out the new error page.
When I hit the URL that we added before that produces the error, now I see the custom error page, which means that the custom error page logic has executed properly. And there you have it: a basic, custom error page. Now, if I want to switch back the development behavior as I work on the application on my local machine, I can always go back and set this variable back to Development. Of course, since all of this is configured in code, this environment variable is only one way to enable or disable the diagnostics page.

For instance, you could enable it for certain users, or maybe certain URLs. Whatever logic you see fit. However you configure it though, error handling is a critical tool and should be included in every application that you build.

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole();

            //generic error message when environment is set to production
            app.UseExceptionHandler("/error.html");

            //dev exception page in dev environment
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.Use(async (context, next) =>
            {
                if (context.Request.Path.Value.Contains("invalid"))
                    throw new Exception("ERROR!!");

                await next();
            });

            app.UseFileServer();

        }

Using Custom Configuration

So, in this video, I'll use ASP.NET Core's configuration library to create a configuration setting just for this feature. Like any other ASP.NET Core library, the configuration library comes in a package that must be added to your project. Lucky for us, the configuration package is a dependency of the logging package that Microsoft included in the default template, which means that it's already been added to the project, so we can just begin using it. The first thing we need to do in order to start using the configuration API is to create an instance of the ConfigurationBuilder object.
This type lives in the microsoft.extensions.configuration namespace, so you'll have to import that namespace in order to use it. Now that we have an instance of the ConfigurationBuilder object, we can start telling it about the various places that the application's configuration settings will be stored. We'll start simply, by importing the environment variables using the AddEnvironmentVariables method. Now that we've wired the configuration source up, we need to make a call to the build method, which tells the ConfigurationBuilder to evaluate all of the configuration sources and build up the configuration object that we can consume in order to actually gain access to the values contained in those configuration sources.
If I add a breakpoint after the build line and run the site in the debugger and inspect the configuration object, I can see that ASP.NET has read a whole bunch of variables from my current environment and put them all into this configuration object, ready to be used. In order to actually access the values of these configuration settings, I simply use the configuration object just like a dictionary. Note that at this point, I haven't actually defined a value for the EnableDeveloperExceptions configuration setting that I'm referencing here, and that's actually perfectly fine.
Any setting that is not defined will simply return a null value. That means that I can now run my application and see this code in action, and I can see that it will skip the registration of the developer exception page, because the configuration setting is not even defined, let alone set to true. However, if I set the EnableDeveloperExceptions environment variable to true and then re-run the site again, I can see that the conditional statement evaluates to true, and the developer exception page is registered.
Here I've shown the most fundamental configuration APIs: a simple dictionary that consists of string values accessed by string keys. But if you look at line 33, I'm comparing the configuration setting to the string "True." But what I really want is for the configuration API to take care of converting the string values into Boolean values for me, and then just give me the Boolean value that I actually want. Unfortunately, the core configuration APIs don't offer that, but there are a set of extension methods, and one of those methods is a method called GetValue of Type T, which looks like this.
Just like in the earlier videos, Visual Studio is highlighting this code as an error because this is an extension method that lives in a separate Nougat package that must be installed before I can use it. So I'll go ahead and add the package from the context menu, and after a few seconds, when it's done downloading, the error will go away, and I can run the site to show the new method in action, converting the string value "True" to a Boolean on the fly.

Likewise, if I go delete this setting from my environment variables, the extension method will not throw an exception, and instead, it'll consider the absence of the configuration variable to simply mean a value of false. Using the configuration API is a great way to dynamically change various aspects of your application in the different environments that you support without having to rebuild and redeploy it.


Populate Configuration Settings

 [Instructor] Now that I've shown you the basics of the configuration API using environment variables, I'll show you how to use another popular configuration source, JSON files. To read configuration settings from a JSON file, all you have to do is add a call to the method, AddJsonFile, on your configuration builder and give it a path to the configuration file. Here I've used the file name config.json but this file can be named anything you like. Just be sure that you specify the full path to the file which you can get from the content root property of the environment object E and V.
Once again, I've ran into another API that lives in a new GET package that I have not added to my project yet. So I'll go ahead and do that. Once the package has been added and downloaded, I'm almost ready to run my application and show the JSON API in action except for the fact that at this point, this JSON file doesn't actually exist. Which means that if I were to run the application, it would just throw an exception. So before I run the application, I'll go ahead and add the file to the root of my project.
I'll populate it with a basic JSON object containing one value. Then now I can finally run the site. When my break point hits, I can inspect the configuration object to see that it is indeed loading this configuration setting from the JSON file that I've provided. The EnableDeveloperExceptions configuration value is set to True. Now, if you think that is cool as I do, you'll love this next part.
The configuration API also allows you to read complex JSON objects. In other words, I can update the JSON object in the configuration file to look like this. Once I've updated the object, you might expect that I'd access this new setting just like I would access a JavaScript object or a C# object with a dot like this. However the configuration API actually uses a column rather than a dot, like this.
Once I've made those changes, I'll run the site again in debug mode just to prove that this syntax works and that the FeatureToggles:EnableDeveloperExceptions setting is still true. One final thing about the configuration API is that it's really versatile and supports a variety of configuration file management approaches. For example, one popular approach is to define one configuration file with all of the default configuration values and then let developers to find their own versions of the file on their local machine, perhaps by changing the extension of the file to .user or something that contains the name of different environments such as development.
To do this with the configuration API, I'll simply add another AddJsonFile method call to a second configuration file named config.development.json. But this time, I'll add in a second parameter set to true to indicate that this configuration file is optional. This parameter tells the configuration API that if the file exists at run time, then yeah, sure, go ahead and read it in. Otherwise if the file is missing, just keep going with the configuration that you've already got.
I'll prove that this file is optional by running the application and seeing that everything continues to work regardless of the fact that I have not created this config.development.json file yet. Then I'll jump back into Visual Studio, make a copy of the config.json file and rename it to config.development.json. Now that I've got two versions of this configuration, I'll remove that EnableDeveloperExceptions toggle from the original configuration file leaving it only in the development.json file.
After I've done this, I'll run the site again and see that we're back to the nice developer friendly error page registeredbecause the configuration API was able to read the setting from the config.development.json file. This ability to load configuration settings from both environment variables and files such as JSON make the configuration API incredibly flexible and extensible.

Dependency Injection

ne of the tenets that drives the ASP.NET Core Frameworks design is a focus on being able to createapplications composed of lightweight and modular components that each do one thing well. One of the main ways it does this, is through built-in support for dependency injection, a development pattern which encourages loose couplingbetween components. To understand the value of dependency injection, let's use the example of the configuration settings that I introduced earlier.
In its current state, this code is a very tightly coupled to the configuration API, since it has to know everything about where these configuration values come from and how to read them from the configuration object. However, all this method really needs is a flag that tells it whether or not to show the developer exception page. So let's create it now. Why should it care if the value for that flag comes from an environment variable or a JSON file? Or even a configuration setting at all. What if this method depended on a simple FeatureToggles class, that looked like this? Then, this method could simply request an instance of this class through its method parameters, like this.
At runtime, this instance will be injected by the ASP.NET Core's dependency injection framework, and then we can simply start using it in our code, without knowing or caring where its' values came from, just like this. These are the basic mechanics of how to consume a dependency using dependency injection, however, if I try to run the site now, ASP.NET Core will throw an exception telling me that it doesn't know how to create an instance of the FeatureToggles class. Luckily, that's a pretty easy thing to teach ASP.NET Core how to do, and it all happens in another method in the startup class that we've been ignoring up until now, the ConfigureServices method.
The ConfigureServices method accepts one parameter. An instance of the iServiceCollection, name services. This object exposes a handful of helpful methods that allow you to configure your dependency injection logic. Most importantly, the AddScoped, AddSingleton and AddTransient methods. Each of these methods allow you to tell ASP.NET Core how to create instances of types when they're requested. The primary differences between them is how long that instance lives.
Instances created using the AddTransient method will have a transient or the shortest lifespan, as ASP.NET Core will create a new instance every time one is requested. For example, if both the configure method that I showed and another class, each request an instance of FeatureToggles, the framework will give them each their own instance and not share anything between them. If you register a type using the AddScoped method, it generally means that ASP.NET Core will only create one instance of that type for each web request.
This approach allows you to share State between different components throughout the same request without worrying about another user's request gaining access to that same data. If you do want to share instances of a type across requests, though, you can use the AddSingleton method. This method will only create one instance of each type for the entire lifetime of the application, which is helpful in cases when you have some common data that you want to share across all users or when you have a type that's particularly expensive to create and is not specific to any particular user or request.
Right now I don't really care how many instances of FeatureToggles ASP.NET Core creates for me, so when in doubt, I always register my types with the AddTransient method. Now when I run the site, my breakpoint hits, which means that ASP.NET Core saw that the configuration method needed an instance of the FeatureToggles class and created one for me. The problem is, it just created the instance using the default Constructor, and I actually want to populate the instance with some values.
Values that I'll get from the configuration settings, in fact. ASP.NET Core allows you to completely control how instancesare created by allowing you to pass the AddTransient method a function, that returns an instance of type. For example, I can create my own instance of the FeatureToggles class, like this. That's nice that I can do this, but it doesn't buy me a whole lot, since it happens to be exactly what ASP.NET Core is already doing for me, so let's make it a little more interesting, by populating its properties from configuration settings.
In order to do that, the first thing I'll need to do is move my configuration object to a property and populate it in the start up Constructor as opposed to the configuration method. Note that I have to bring along the reference to theIHostingEnvironment, since I'm still pulling in the ContentRootPath from that object. Don't worry though, ASP.NET Core already knows how to inject this type, even before the configuration services method is executed.
With that in place, I can reference the configuration object when I create a new instance of the FeatureToggles class. Then I can try to run the site again and see the whole thing in action. When it runs, I can see that the FeatureToggles objectcontains the values from the configuration settings that I populated in my method. And there it is, dependency injection in action. If you're thinking that this seems like a lot of work just to decouple a little bit of configuration logic, then I don't really blame you.
Maybe it is, however, ASP.NET Core AND ASP.NET Core MVC both leverage dependency injection throughout the framework. And this simple example is a really great way to get acquainted with the concepts at the most basic level. Don't worry, though, I'll show you much more complex examples in just a little bit.
MVC Pattern
At this point in the course I've shown you some of the basic building blocks of an ASP.NET Core web application using low-level APIs to respond to requests with simple logic and static files. What we need is a framework that takes care of all this mundane middleware plumbing code and lets us focus on writing our application logic instead. What we need is the ASP.NET Core MVC framework. In order to truly to understand the ASP.NET Core MVC framework, we must first define the design pattern that it was named after: The Model-View-Controller or MVC Pattern.
The MVC pattern is a user interface design pattern that promotes separation of concerns across multiple application layers. In other words, instead of putting all the View Logic, Application Logic, and Business Logic for an application in a single place, MVC promotes separating each of them into specific classes, each with a small, specific set of responsibilities. Separation of concerns is a powerful principle that is frequently used in the design of platforms and frameworks.
For example, web pages in the early days of the web contained markup that combined the layout, style, and even data all in the same document. Over the years standards based on separation of concerns emerged and what was once one document is now split into three parts: an HTML document, which mainly focuses on the structure of content, one or more CSS style sheets that define the style of the document, and JavaScript to attach behaviors to the document.
In the context of the Model-View-Controller pattern, separation of concerns is used to divide the application into three key components. Models, Views, and Controllers. The view is exactly what it sounds like. It's the part of your application that the user sees and interacts with. In a web application the view is everything that gets rendered down to the browser;HTML, CSS, and JavaScript. The view's single responsibility is to deliver a high quality, good-looking user experience to the user and nothing else.
In other words, your goal should be to make that view as pretty and as dumb as possible, relying on controllers and models to take care of all of the smarts of the application and displaying the result. This diagram shows a dotted line from the view to the controller indicating that the view may call back to the controller in order to execute logic that's outside of the view's responsibilities. Be careful here. It's always tempting to make the view more intelligent than it should be but you'll want to avoid that at all costs as it typically results in application code that is more difficult to change and maintain.
You'll know you've done it right when you can completely throw away your view and start from scratch with relatively little effort because the real logic, the application, is defined elsewhere distributed between the controllers and the models.Controllers are the traffic cop of your application, controlling application workflow as the user interacts with the view. For example, I'll soon be showing you how to create a view that accepts the text for a new blog post and displays a button to create that new blog post in the system.
When you click on that button, the view will tell the controller about the text that the user has entered. But after that it's up to the controller to determine how to react; perhaps by first executing some validation logic. And then if the validation succeeds, the controller will then call the data access component to save the blog post. If the validation or the data access component fails, the controller will choose the appropriate view to display to the user depending on the error that occurred.
Notice how the controller spends its entire life orchestrating interactions between components. This is important and one of the biggest mistakes that a lot of developers make is making the controller too smart by defining application logic rather than orchestration logic. It's best to put all that application logic into the model and let it do the heavy lifting. The term "Model" has come to mean many different things over the years. Perhaps the most popular definition refers to the data structures that are used throughout your application.
And while the model certainly does define data structures, it's also much more than that. In the MVC pattern, the model is the heart of the application. It's where all your business logic lives. Logic such as business processes, validation rules, or even the logic of integrating with other systems. MVC applications with a good separation of concerns will contain a model layer that is completely isolated from the platform or environment that it's operating under.
In other words, though I am defining the term "Model" in the context of an ASP.NET web application, if I'm filing a strict separation of concerns, I could actually use the same exact model in a Windows Forms WPF or even a console application.Practically speaking, you won't really need to worry about creating a model that could be used anywhere, but as far as separation of concerns in good design goes, it's a good goal to aspire to. So if that's the MVC design pattern, what is ASP.NET Core MVC? Well, ASP.NET Core MVC is Microsoft's implementation of the MVC design pattern on top of the ASP.NET Core platform.
That is, it's a framework that is built on top of those core building blocks that I showed earlier in the course that helps you create web applications consisting of models, views, and controllers with a strong separation of concerns. Now that I've got all those high level concepts out of the way, let's get back to the good stuff.




Add ASP.NET MVC to your ASP.NET Core application


Now that you know what the ASP.NET Core MVC Framework is, it's time to add it to our application. Like most other functionality, the ASP.NET Core MVC Framework lives in a package that this project does not yet reference. So, we'll need to add that package, and I'll do this with the shortcut that I've shown in other videos by simply writing the code to register the MVC middleware in my application: app.UseMvc(); Then I'll use the context menu to tell Visual Studio to add the package.
Once the package is added, and I begin to get intellisense, I can see that this method also accepts an optional parameter of a configuration function. In this function, you can define the route patterns that the ASP.NET Core MVC middleware should be listening to. It looks like this: I'll explain the details of what's going on here in a later video. All you really need to know right now is that this string represents the URL to be matched and each of these placeholders defines a section of the URL and gives it a name.
For example: if I navigated to /Admin/Users/1 that would map to the Admin controller, the users action on the controller,and the ID of one. Now, this call is a crucial part of configuring ASP.NET Core MVC, but it's only half of what is required to demonstrate. Let me run this site and show you what happens. This site is throwing an error because it is not yet been fully configured; in other words, just registering the middleware with the useMvc function was not enough.
The reason I wanted to run the site was to show you this error message. It says that the ASP.NET Core MVC middleware expects service information, which refers to the fact that it uses dependency injection and those components need to beconfigured separately, in addition to the useMvc method. Luckily, even though the framework doesn't register thoseservices for us automatically, it does give us a simple method to call, which will configure them using the default settings and it even tells us right here how to call it.
"Please add all the required service by calling 'iServiceCollection.Add.Mvc' inside the call to 'ConfigureServices(...)' in the application startup code." So, let's go ahead and do that. Note that when I write this code, Visual Studio warns me that it doesn't know about this extension method because it lives in yet another package. So, I'll use the context menu to add a reference to that package and make this error go away. OK, now that we have both the middleware registered and its services configured let's run the site again and see what happens.
What we're seeing here is the static HTML homepage again, which actually means that everything is working. It means that the ASP.NET Core MVC middleware is configured, but it didn't have any controllers registered to handle the request so it just let the request pass on through, through the static file middleware that I registered earlier, which offered up this staticindexed .html page.

        // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddTransient<FeatureToggles>(x => new FeatureToggles
            {
                EnableDeveloperExceptions = 
                    configuration.GetValue<bool>("FeatureToggles:EnableDeveloperExceptions")
            });
            //services configured
            services.AddMvc();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(
            IApplicationBuilder app, 
            IHostingEnvironment env, 
            ILoggerFactory loggerFactory,
            FeatureToggles features
        )
        {
            loggerFactory.AddConsole();

            app.UseExceptionHandler("/error.html");

            if(features.EnableDeveloperExceptions)
            {
                app.UseDeveloperExceptionPage();
            }

            app.Use(async (context, next) =>
            {
                if (context.Request.Path.Value.Contains("invalid"))
                    throw new Exception("ERROR!");

                await next();
            });
            //middleware registered
            app.UseMvc(routes =>
            {
                routes.MapRoute("Default",
                    "{controller=Home}/{action=Index}/{id?}"
                );
            });

            app.UseFileServer();

        }
    }
}

Handle requests with controllers

Controllers are the traffic cop of your MVC application. They are responsible for receiving the request and figuring out what to do with it. In an ASP.NET Core MVC application, controllers are nothing more than classes. So in order to create a new controller, all you've got to do is add a new class to your application. Though ASP.NET Core MVC will find controller classes regardless of where they live in your project, the standard convention, simply for the sake of keeping your project organized, is to put all of your controller classes in a folder named Controllers.


When I navigate to that URL, I can see that hardcoded string return back to me. This may seem a lot like the examples that I showed earlier in the course, where I responded to every single request with the same string, but the difference here is that this response is tied to the names of the controller and the action that I just created. That means that now, if I try navigating to other URLs in my site, I get the same blank page that I got in the earlier videos when ASP.NET Core didn't know how to handle the requests, because this controller only handles requests to the /home/index URL because of the way that I configured ASP.NET Core MVC when I registered it in the startup class.
With this in mind, I'll create another controller named BlogController, which I'll eventually use to render the blog post content to the site. In the HomeController that I just created, I replaced the return value with a simple string just to prove that controller actions are merely methods. However, you're rarely going to do that, and instead, you'll be returning ActionResult objects with information that ASP.NET Core MVC will use to figure out how to respond to the request.
There are many different types of ActionResult objects, and I'll show you a few of them throughout the course. The simplest type of ActionResult is the content result, which you can return by simply creating an instance of the ContentResult object, like this. In ASP.NET Core MVC, every controller action returns an ActionResult, even the action in the HomeController that I showed earlier. It's just that ASP.NET Core MVC was nice enough to convert that string valueinto a content result, like this.

So with this new controller action in place, I now have two routes in my application that I can hit. /home/index, and /blog/index. Now that I've shown you how to handle web requests in ASP.NET Core MVC by using controllers, let's move on, and I'll show you how to pass data to your controller actions through simple method parameters.

namespace ExploreCalifornia.Controllers
{
    public class BlogController : Controller
    {
        // GET: /<controller>/
        public IActionResult Index()
        {
            return new ContentResult { Content = "Blog posts" };
        }
    }
}

Pass parameters to controller actions


From Startup.cs:

app.UseMvc(routes =>
            {
                routes.MapRoute("Default",
                    "{controller=Home}/{action=Index}/{id?}"
                );
            });

BlogController:

namespace ExploreCalifornia.Controllers
{
    public class BlogController : Controller
    {
        // GET: /<controller>/
        public IActionResult Index()
        {
            return new ContentResult { Content = "Blog posts" };
        }
       // nullable int
       //        public IActionResult Post(int? id)
        public IActionResult Post(String id)
        {
            return new ContentResult { Content = id };
        }

    }
}

URLs that this controller specifies:

localhost:8080/blog/post/id OR
localhost:8080/blog/post?id=test

ne great thing about controller actions is that they really are just methods, which means that if you want to pass data into them, you just go ahead and define a parameter on the method, and ASP.NET Core MVC will automatically populate that parameter from the request. For example, in the blog application I'm building, I'll need to be able to access a specific blog post by some kind of identifier. And I'll do that by passing the value of that identifier through a method parameter on the action.
To demonstrate, I'll add another action to the blog's controller by simply defining a new method named Post. I'll have this new method accept a string parameter named id. And I'll have this method simply return the value of the parameter right back to the user as content. The name of this id parameter is very important as ASP.NET Core MVC uses this name to extract the value from somewhere in the request, such as a query string or the body of a form post.
In this case, I used the name id because I wanted to pull this value from the id placeholder in the route template that I showed earlier. Since this default route already includes the id placeholder, I can now run the application and navigation to /blog/post/some identifier, and it will echo that third value back to me. Alternatively, if i don't want to pull the value from the route, I can instead pass a query string parameter with the same name to achieve the same result.
ASP.NET Core MVC will even convert the request values from strings to whatever type that I want. This feature is called Model Binding. And in later videos, I'll use it to populate properties of entire objects. But for now, I'll show you how Model Binding works with a few different primitive types. For example, I can change the type of the id parameter to an integerand then update the call to the Content method to display the string value of the integer.
When I navigate to /post/test again, I see that it returned zero. Because the string test is not a valid integer value. The reason it's showing me zero is because instead of throwing a parsing exception, ASP.NET Core MVC just assigns the parameter to the default value of the integer type, which happens to be zero. However, if I navigate to /post/123, I'll see the value 123 returned.
Likewise, I can update the parameter to accept a Boolean value. And ASP.NET Core MVC will map the string true to the Boolean value true. If, however, I try any other value that does not parse into the true Boolean value, ASP.NET Core MVC will convert that value to the default Boolean value which happens to be false. While this default behavior is often something you're looking to do, sometimes you'd rather be able to tell the difference between a value that the user explicitly entered and a value that just failed to parse correctly.
In other words, if I switch back to the integer type and I want to be able to differentiate between the value of 123 and a value of something that doesn't map to an integer like test, there are a couple of things I can do. And both of them are just C# features that take advantage of the fact that controller actions are just regular old methods and these features actually have nothing to do with any functionality that ASP.NET Core provides. The first option is to simply use a nullable integerinstead of the primitive type.
This way, whenever ASP.NET Core MVC fails to parse the value that's passed in, it will still use the default value, except now the default value will be null rather than zero, which will allow me to tell the difference between when a user passes in an invalid value and when they actually pass in the value zero. The second approach is to use the C# optional parameter syntax to provide C# with a default value explicitly.
Now when I pass an invalid value in, it will map to that default value that I just defined. Either of these options are completely legitimate. And which one you choose will depend on your needs and your personal preference. Regardless of the approach that you choose, you'll pretty much always want to take advantage of MVC's Model Binding rather than manually extracting and converting values from the request yourself.

Understand routing





Earlier in the course, I introduced you to the basic concepts of routing by showing how a URL maps to an action method on a controller class and even how to extract action method parameters from values in the URL. If you thought that was powerful, that's just the beginning of what routing can do. I mentioned previously that all of this routing magic is defined in the call to add MVC to register the ASP.NET Core MVC middle ware in the start up class in the form of a route template.
A pattern that maps URLs to controllers and actions using named placeholders. You can register as many routes as you want but it's this one route template that is generic enough to map a URL to just about any controller and action that I can create. Once it maps those parts of the URL to those placeholders, it tries to find the controller and action that match those placeholders. This is where the name of the controller class becomes significant.
By default, ASP.NET Core MVC follows the convention that all controller classes need to end with the suffix controller. So, when it starts up, ASP.NET Core MVC looks through all your classes finds the classes whose names end with controller,strips off that suffix and then uses the rest of the name to match against the controller placeholder coming from the URL.Then, it finds all of the public methods in that controller class and registers them as potential actions on that controller.
The end result of all of this is that when I navigate to a URL such as home/index ASP.NET finds the class named home controller and the method named index on that class and executes it. ASP.NET Core MVC also allows me to registerdefault values to each of the placeholders in the route using this equal syntax that you can see in this route that I've defined. Likewise, I can use the question mark syntax to indicate the parts of the URL pattern that are completely optional as well.
That means, that when they're missing the route will still be considered a match but the values of these placeholders will be null. So, if I were to translate the URL pattern that I gave to ASP.NET Core MVC into English it would say, look for a URL that follows the pattern slash controller slash action slash id. But, if you're missing that third part of the URL that's okay, if you're missing the second part of the URL, the part that defines the action, then, default that to index.
And if you're also missing the first part of the URL, the part that defines the controller name then default that to home. The end result, due to these default values there are actually three ways that I can get to the index action on the home controller slash home slash index slash home and just simply slash. ASP.NET Core MVC also allows you to provideconstraints on the place holders in your routes to limit the URLs that the route will match.
So, in our previous example, I only wanted the post action to execute when the third part of the URL, the ID part is an integer. The syntax to do this is actually quite simple, it's just a colon followed by a type. Here I've indicated that the value and the id portion of a request must be a number meaning that now this route will not match a URL that has non numeric characters in these sections of the URL. It's important to note that the question mark is still attached to the ID parameter to indicate that it is still optional.
In other words, that third part of the URL doesn't have to exist but if it does exist it does have to be a number in order for the route to be a match. The int constraint is only one of the many built in route constraints. Here is a list of all of the rest as taken directly from the online documentation at docs.asp.net. With this variety of built in constraints it should be pretty easy to limit your routes to exactly what you're looking for.




Customize your application's URLs



 I don't like to be restricted by a single convention across my entire site. Instead I like to have the ability to attach any custom URL that I want and create vanity URLs such as slash log in, that don't necessarily have anything to do with the name of the controller or the action that handles them.


To help demonstrate why we might want to customize our site's URLs, let's take a look at how our default route configuration drives our URLs right now. Keep in mind that our default route currently follows the pattern of slash controller, slash action, slash ID which means that if we want to view a blog post with the ID of one, then we'd have to navigate to slash blog, slash post slash one. However, wouldn't it be nice if we could make this URL a little more meaningful.

Like say, slash blog, slash the year, 2015 slash the month, maybe six, slash the title of the post such as my first blog post.Luckily, this is pretty easy to do. To begin, let's find the controller action that we want to customize. The post action on the blog controller. In order to customize the URL for this controller action, we'll simply place the route attribute on top of the action and pass it a string parameter that defines the custom route pattern to apply to just this action.

Since we want our URL to include the year, month, and title of the post, our pattern might look like this. Now that I have this route parameter defined, I can add those parameters to my controller action. An integer parameter named year, another integer parameter named month, and a third string parameter named key. Note that the order that these parametersappear in the controller action does not have to match the order that they appear in the route pattern.

You can put them in an order you like and ASP net core MVC will map them by name correctly. Since I don't yet have any logic in this action, I'll simply print the value of these parameters to show that they're mapped properly. Now, when I navigate to this URL I can see that my action is hit and this values are mapped properly. I can even update the route to use a couple of the constraints that I showed earlier. I can use the range constraint to make sure that the value for the month is between one and 12.
And maybe use the min constraint to make sure that the year is at least let's say 2000. With this in place, I'll hit control F5 to run the site and see it in a browser. When the URL seems like it matches the pattern but doesn't meet these constraints,MVC does not map it to this controller action and we end up with an empty page. The neat thing about route attributes is that you can apply them to both the controller action as I've shown here, and the controller itself, to define a root path that all of the route attributes apply to the individual controller actions will inherit.
For example, I can rewrite this route by removing the blog part at the beginning and promoting it up to the controller.When I apply the route attribute to the controller like this all of the other route attributes defined on actions on this controller will inherit the same root route path. Meaning that I can avoid repeating it over and over again for each action and potentially have some of them get out of sync with each other. Applying the route attribute at the controller level does not automatically apply the custom route to actions that don't have the route attributes applied.
In the cases where you don't want to add anything more to the base route such as cases like the index action shown here,you can simply use an empty string like this. Note that applying the route attributes to the controller actions like this removes it as a candidate from matching the more generic routes defined in the start up class. That means, that once a route attribute has been defined, the only way that that action can ever get executed is if it matches the route defined in the attribute.
Usually that's exactly what you want. But sometimes it might be an unexpected side effect, so just be sure to watch out for it. Whether you decide to use the attribute routing approach or define a global route, now that you've seen both styles in action, one thing is for sure, ASP net core MVC's routing functionality sure is powerful.

namespace ExploreCalifornia.Controllers
{
    [Route("blog")]
    public class BlogController : Controller
    {
        [Route("")]
        public IActionResult Index()
        {
            return new ContentResult { Content = "Blog posts" };
        }

        [Route("{year:min(2000)}/{month:range(1,12)}/{key}")]
        public IActionResult Post(int year, int month, string key)
        {
            return new ContentResult {
                Content = string.Format("Year: {0};  Month: {1};  Key: {2}",
                                        year, month, key)
            };
        }
    }
}


Render HTML with Razor




 In this chapter, I'm going to show you how to deliver rich client size experienceswith HTML and the browser by creating dynamic ASP.NET Core MVC views using the Razor syntax.
Since returning an HTML view back to the user is the most common task that an ASP.NET Core MVC controller action does, the Visual Studio Controller template includes a call to the view method in every new controller class. Previously, I deleted that generated code just to demonstrate how controller action respond to request but now that I'm ready to return in HTML view, let me revert back to that original code and see what happens. Now, I haven't created a view yet but let's just run this anyway.
Unsurprisingly, I get an error. Our controller action ran and told ASP.NET Core MVC to render the view with the same name as the controller action, Index. However MVC couldn't find the view by that name and actually tried looking in a couple of different places. Notice the places that MVC says that it's looking for the view, /Views/Home/Index.cshtml and /Views/Shared/Index.cshtml.
In other words, it's looking for a .cshtml file with the same name as the action that was called, in this case Index, and it's looking for that file in a couple of different folders. The first folder it looks for is a folder with the same name as the controller that's handling the request. In this case, that controller is named Home. Using this convention, we can put all of the views for our Home controller into one folder so they're easy for us to find and work with.
Next is the Shared folder. This is a folder where you can put all of the views that are used across multiple controllers in your application. I'll show you how to use both of these folders in this chapter but I'll just start with the Home folder first.Since we have no views folder at all in our project, the first thing we need to do is create it. Then we can create the Home folder right under it. Now that we've got the Home folder to hold our views, I'll create the Index.cshtml view that ASP.NET Core MVC is looking for.
The cshtml extension indicates that the view is defined in the Razor syntax. A syntax that lets you combine HTML and C# code all in one file. That means I can start by simply moving our existing .html file from our www root folder into this new folder and then rename it to the .cshtml file extension. And that's it. Since HTML is perfectly valid Razor syntax, we don't have to change anything else in the file in order to make it render properly.
Now I can just run the application again and refresh our page. And instead of that error message, I see my wonderful home page again. Only this time it's not the static Index.html file but a Razor view rendered by our controller action. Notice also how all of the CSS and image files continue to load just fine because the file server middleware is still serving themfrom the www root folder just as it was before. Nothing has changed there.

Render dynamic content with Razor




For example, let's say that I want to add a copyright to my page, and make sure that it always emits the current year, so that I don't have to remember to update it all the time. I can just do this. Notice how I get full intellisense when I begin writing code after the @ sign. Now when I run this page and scroll to the bottom, I can see that Razor has evaluated that expression, and rendered the resulting value as text right into the page.
That's a pretty simple example, but the real power of Razor lies in HTML helpers. HTML helpers are methods provided by the ASP.NET Core, ASP.NET Core MVC, and many other libraries. And they're able to emit entire sections of dynamic HTML with a single method call. For instance, the HTML helper that you'll probably use the most in your ASP.NET Core MVC applications is the Html.ActionLink helper, which generates anchor tags, based on a controller and an action name.

<li> <a href = "/blog" title = "read our blog!"> Read Our Blog! </a> </li>
OR
<li> @Html.ActionLink("Read Our Blog!", "Index", "Blog", null, new { title = "read your blog!" }) </li>
OR
<li> <a href = "@Url.Action("Index", "Blog")" title = "read our blog!"> Read Our Blog! </a> </li>

For example, let's scroll to line 45 in our index view to find the link to the blog section of our site. By looking at it, I can tellthat this path will end up mapping to the index action on the blog controller. But, if I change that route, I'll want this link to stay in sync with that new route, ideally without me having to search for it and replace it manually in all of our views.Instead, I can replace this whole anchor tag, with a call to Html.ActionLink, like this.
This version of the action link helper takes three parameters. The first parameter is the text to show in the link, or what I want the user to read on the page. The second parameter is the name of the action that I want to link to, and the third parameter is the name of the controller that the action lives in. Notice how I only use the beginning of the name of the controller type, and drop the word controller from it. Now, when I run this application, the link still looks and behaves as it did before.

Reuse shared HTML markup with layouts



Navigate around the Explore California site a little bit and notice how every single page contains the same common sections, such as the header, footer, and even the left sidebar section of the page. This is a great thing, as it gives a consistent look and feel throughout the site. However, it's really painful to change each instance of those common elements across all pages in the site. Luckily, ASP.NET Core MVC allows us to define special Razor pages whose sole purpose it is to define this common layout and render content from individual pages inside of this layout.
These type sort of Razor pages are referred to as layouts, and they're a great candidate to live in that shared Views folder we saw ASP.NET Core MVC looking for earlier. To demonstrate how they work, let's create the new Shared folder under the Views folder. Then, I'll make a copy of our index.cshtml page into this new Shared folder and rename it _Layout.cshtml.Now, there's nothing special about the underscore or the layout in this file name.
Those are just naming standards that I, and a lot of other people, like to use to indicate that this file is a layout and not a full page. Next, open up the newly renamed _Layout file, copy the contents of the main content section to your clipboard to save them for later, and replace them with this snippet of code, @RenderBody(). This is a C# method call that tells Razor to take the body of the view that has been rendered and put it at this location in the page.
With this layout in place, we can go back to our index.cshtml page and modify it to take advantage of this new shared layout. To do that, simply replace all of the content in this file with these couple of lines and only the content that we wish to display on this page. These beginning lines are more C# code that is setting the Layout property of the view to tell ASP.NET Core MVC that this view should be wrapped in the layout named _Layout.
How does ASP.NET Core find that layout? Well, you probably guessed, the file named _Layout.cshtml in the Shared Views folder. Now, when we run the site and refresh the page, it looks exactly the same. Only, this time, the main content is getting rendered by the index view, and the layout of the page is getting rendered from the layout view. Likewise, I can convert my BlogController actions to return views rather than the hard-coded content they're returning now.
First, I'll update the controller actions so that they make a call to the view method to return view action results. Then, I'll add the corresponding index view in the Blog view folder and populate it with some content. With these changes in place, I can run the site again and see that my blog page now shows this new view. This approach is great if you only have one section of your application that you want to change on each page, but what if you had multiple sections of content? For example, right now, the content in the header of this application has some text and a link, but what if we wanted to controlthe content of that header on each page? Luckily, we're not just restricted to one section.
MVC also offers another method named RenderSection that allows you to define additional sections of content that pages may control. To see it in action, I'll copy the content that's currently in the action call element and replace it with a call to RenderSection. This method has one required parameter, the name of the section, and I'll call this one header. Then, in order to use this section, I can go to the views that use this layout and tell Razor what content I want to render in this section by using the section keyword followed by the name of the section, just like this.
Note that it's not really important where in the view I define this section. It could be at the beginning like this, it could be at the end, or, really, anywhere else. Now when I run the home page, I see that this content still shows, just like it did before.However, if I hit another view that uses this layout, I get an error. This is MVC letting me know that I must define a section if I'm going to use this layout. The other alternative I have to defining a section here is to use the second optional parameterto the RenderSection method.
This is a Boolean value, which indicates whether views are required to define this section or not. So, to make this error go away, I'll just set this value to false to indicate that it's not a required section. Now when I run my site, I can visit my blog page and see that the page still renders, even though I haven't defined the section. But now what if what I really want to do is define some default content in the layout and then allow views to override that content, but only when they want to?In order to do that, I can use the IsSectionDefined method in my layout like this.

Now when I navigate to pages that don't define this header section, they'll just get the default content, but on pages that do define this header content, we'll show that custom content instead. Now that I've shown you how to render basic Razor views with layouts, let's get a little more advanced.

INDEX.CSHTML
@{
    Layout = "_Layout";
}

@section header {

  <h1>Explore our world your way</h1>
  <a href="/tours.htm" title="Find your tour!"><h2>Find your tour</h2></a>

}

<article id="mainArticle">
    <h1>Tour Spotlight</h1>
    <p class="spotlight">This month's spotlight package is Cycle California. Whether you are looking for some serious downhill thrills to a relaxing ride along the coast, you'll find something to love in Cycle California.<br /> <span class="accent"><a href="/tours_cycle.htm" title="Cycle California">tour details</a></span></p>
    <h1>Explorer's Podcast</h1>
    <video controls poster="/images/podcast_poster.jpg" width="512" height="288" preload="none">
        <source src="_video/podcast_teaser.mp4" type="video/mp4" />
        <source src="_video/podcast_teaser.webm" type="video/webm" />
        <source src="_video/podcast_teaser.theora.ogv" type="video/ogg" />
    </video>
    <p class="videoText">Join us each month as we publish a new Explore California video podcast, with featured tours, customer photos, and some exctiing new features!<span class="accent"><a href="explorers/video.htm" title="Video Podcast">Watch the full video</a></span></p>
</article>




_LAYOUT.CSHTML
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Welcome to Explore California</title>
<meta name="description" content="A lynda.com example of HTML5 and CSS3">
<meta name="keywords" content="html5, css3, lynda, local storage, canvas, forms, semantics, web apps">
<!--make sure mobile devices display the page at the proper scale -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link href="/css/main.css" rel="stylesheet" type="text/css" media="screen, projection">
</head>
<body id="home" class="no-js">
<div id="wrapper">
  <header id="mainHeader"> <a href="/" title="home" class="logo">
   <!-- I need this div because IE is an affront to mankind-->
    <div>
    <h1>Explore California</h1>
    </div>
    </a>
    <nav id="siteNav">
      <h1>Where do you want to go?</h1>
      <ul>
       <li><a href="/tours.htm" title="Our tours">Tours <br /><span class="tagline">follow our bliss</span></a>
          <ul>
            <li><a href="/tours.htm" title="Our tours">All Tours</a></li>
            <li><a href="/tours.htm" title="find tours">Tours by Activity</a></li>
            <li><a href="/tours.htm" title="find tours">Tours by Region</a></li>
            <li><a href="/tours.htm" title="find tours">Tour Finder</a></li>
          </ul>
        </li>
        <li><a href="mission.htm" title="What we believe">Mission <br /><span class="tagline">what makes us different?</span></a></li>
        <li><a href="resources.htm" title="planning resources">Resources <br /><span class="tagline">plan your trip</span></a>
          <ul>
            <li><a href="resources/faq.htm" title="Got questions?">Tour FAQs</a></li>
            <li><a href="resources/additional_resources.htm" title="additional resources">Tour Information</a></li>
            <li><a href="resources/terms.htm" title="terms and conditions">Site Terms</a></li>
          </ul>
        </li>
        <li><a href="explorers.htm" title="Our community">Explorers <br /><span class="tagline">join our community</span></a>
          <ul>
            <li><a href="explorers/join.htm" title="join our community">Join the Explorers</a></li>
            <li><a href="/blog" title="read our blog!">Read our Blog</a></li>
            <li><a href="explorers/gallery.htm" title="contributor photos">Tour Photos</a></li>
            <li><a href="_video/EC_podcast_full version.mov" title="check out our podcast">Video podcast</a></li>
          </ul>
        </li>
        <li><a href="contact.htm" title="contact us" class="last">Contact <br /><span class="tagline">we're listening</span></a>
          <ul>
            <li><a href="support.htm" title="need help?">Support</a></li>
          </ul>
        </li>
      </ul>
    </nav>
  </header>
  <section id="actionCall">
@if  (isSectionDefined("header"))
{
  @RenderSection("header",  false)
} else 
{
     <h1> something </h1>
}
  </section>
  <div id="contentWrapper">
  <section id="mainContent">
    @RenderBody()
  </section>
    <aside id="secondaryContent">
        <div id="specials" class="callOut">
            <h1>Monthly Specials</h1>
            <h2 class="top"><img src="/images/calm_bug.gif" alt="California Calm" width="75" height="75">California Calm</h2>
            <p>
                Day Spa Package <br>
                <a href="/tours/tour_detail_cycle.htm">$250</a>
            </p>
            <h2><img src="/images/desert_bug.gif" alt="From desert to sea" width="75" height="75">From Desert to Sea</h2>
            <p>
                2 Day Salton Sea <br>
                <a href="/tours/tour_detail_cycle.htm">$350</a>
            </p>
            <h2><img src="/images/backpack_bug.gif" alt="Backpack Cali" width="75" height="41">Backpack Cali</h2>
            <p>
                Big Sur Retreat <br>
                <a href="/tours/tour_detail_cycle.htm">$620</a>
            </p>
            <h2><img src="/images/taste_bug.gif" alt="Taste of California" width="75" height="75">Taste of California</h2>
            <p>
                Tapas &amp; Groves <br>
                <a href="/tours/tour_detail_taste.htm">$150</a>
            </p>
        </div>
        <div id="trivia" class="callOut">
            <h1>Did You Know?</h1>
            <p>California produces over 17 million gallons of wine each year!</p>
        </div>
    </aside>
  </div>
  <footer id="pageFooter">
  <section id="quickLinks">
  <h1>Quick Nav</h1>
    <ul id="quickNav">
      <li><a href="/" title="Our home page">Home</a></li>
      <li><a href="/tours.htm" title="Explore our tours">Tours</a></li>
      <li><a href="mission.htm" title="What we think">Mission</a></li>
      <li><a href="resources.htm" title="Guidance and planning">Resources</a></li>
      <li><a href="explorers.htm" title="Join our community">Explorers</a></li>
      <li><a href="contact.htm" title="Contact and support">Contact</a></li>
    </ul>
  </section>
  <section id="footerResources">
  <h1>Resources</h1>
    <ul id="quickNav">
      <li><a href="resources/faq.htm" title="Our home page">FAQ</a></li>
      <li><a href="support.htm" title="Need help?">Support</a></li>
      <li><a href="resources/legal.htm" title="The fine print">Legal</a></li><li><a href="login.htm">Login</a></li>
    </ul>
  </section>
  <section id="companyInfo">
  <h1>Contact</h1>
  <h2>Explore California</h2>
      <p>5605 Nota Street<br />
        Ventura, CA 93003</p>
      <p>866.555.4310<br />866.555.4315 <em>(24 hour support)</em></p>
  </section>
  </footer>
</div>
</body>

</html>

Pass data from the controller to the view


 Now that I've shown you the basics of working with Razor Views, let's see how controllers can pass data to the view so that the view can display that data to the user. For example, let's say we want to be able to set the title, author, date of the post, and the body of the post as variables in the post action of the blog controller, and pass that info to be rendered in the view. The easiest way to do this is with the ViewBag property. This property is a dynamic object that is accessible both on the controller and the view.
So, whenever we set a value on this object in the controller, it will also be available in the view. And since it's dynamic, we can just access it as though the property already exists, like this. Then, we can create the view for this action, and just read those properties from the ViewBag to render them right in the page in the appropriate places. Now, when we run the site and access the blog post, we can see the data we've set in the controller getting passed to the view, and rendered in the browser.
There's one huge caveat to this approach, however. The ViewBag property is a dynamic object, which is a double-edged sword. On one hand, it's really easy to work with since you don't have to worry about types. On the other hand, you don't have any type information, so Razor can't give you any IntelliSense, nor can it protect you from type conflicts, such as when you expect that a value is a string when it's really an integer, and then you try and execute a string method on it, and it fails. The answer to this is to pass a strongly typed data model, from your controller to your view, in order to get full IntelliSense and type checking right inside your file.
Now, despite all of these warnings, the ViewBag approach can be useful in many cases.


Render data with strongly typed views


While the ViewBag property is a convenient way to pass data around, its dynamic nature often leaves a lot to be desired. So, in this video I'm going to show you an alternative to the dynamic ViewBag approach for passing data from a controller to a view, which is to pass a strongly typed model into your view instead. In order to create a strongly typed view, we first need to create a type that we can use as our model. Before we do that, let's create a model's folder in the root of the application to hold all of our model classes in.
It's important to note that like the controller classes, it really doesn't matter to MVC where you model classes live. You'll often see this models folder as a practical convention. But these models can live anywhere, even in another project. In fact, that's usually a pretty good idea. Anyway, regardless of where it lives, let's create a brand new class. Just a simple type named post, with a couple of properties in it. Title, posted, author, body et cetera. Once we have this, we can refactor our ViewBag properties settings approach, and instead, set those same property values on an instance of this new post class.
Then, we can pass this instance right to the view, as a parameter to the view method that we're calling at the end of the controller action. With all that in place we can jump to the view, so we can start consuming this model. The first thing we're going to do is tell Razor, that the type of the model is the post type. We can do this by adding the following line to the beginning of our file. Then, we can replace all of those existing references to ViewBag with references to the strongly typed model, which we can access through the model property.
And look, as we do this, we go complete Intellisense. When we're done, we'll go ahead a refresh the page to make sure that it'll all work. Once again, we're greeted with the same exact view as before, because we didn't actually change any of the output. We just improved the way that we are passing data from the controller to the view.





Reuse view markup with partial views


Now that I've shown you how to render full pages of content using Razor views and layouts, let's take a look at how you can reuse sections of Razor markup throughout multiple views using the partial view technique. Put simply, partial views allow you to take chunks of your views and put them in their own separate files and then stitch them back together again to create full views. This helps make your views more manageable, not to mention it gives you the ability to reuse the same view in multiple places throughout your application.
Check out our blog landing page. Right now, this page just has a placeholder, but what I'd like to do is list out the latest couple of posts here. Assuming that I want the blog post markup shown on the landing page to look exactly like the post markup shown on the individual post pages, I could implement my landing page by copying and pasting the Razor markupfrom this post view that we just created and that'll work just fine. In fact, that's a perfectly legitimate way of doing it, but if I wanted to reuse the same exact markup in both places, what I really want to do is create one partial view that both of them can share.
To do this, I'll create a new view and because I want any controller to be able to use this view, I'll put it in the Shared folder. In fact, to save time I'll just copy my existing Post.chtml file into the Shared folder and rename it to _Post.chtml.Again, there's nothing special about the underscore in this name. It's just a convention to tell other developers that it's a partial view and to help differentiate it from the full view of the same name that still exists.
So now that I have this copy, I'll open the file up and then simply remove the layout property and that is my partial view. In other words, there's nothing inherently different between regular Razor views and partial Razor views other than the way that they're used. Now that we have this partial view in place, it's time to use it. Let's start by rewriting the original full Post.chtml view to take advantage of this new shared view. To do that, I remove all of the markup, but I'll leave the lineswhere I'm setting the layout property so this will continue to render as a full view.
Then I'll replace that markup with a single call to the Html.Partial HTML helper and I'll give it the name of the partial viewthat I just created. With that in place, I can run my application and view one of my posts to make sure that it still works.Once again, we have another somewhat underwhelming demo. So let's get to the good part and actually reuse this same view on the landing page. And once again, I'll start by removing that placeholder text and I'll replace it with the same call to Html.Partial.
What this would do is render one single post, but keep in mind that I actually want the landing page to render multiple posts. Since we can write some C Sharp code to iterate over a collection of posts, this is actually pretty trivial. First, I'll need to tell Razor that I expect the model to be a collection of post objects. Then I can just write a C Sharp foreach loop to iterate over that collection. Next, I'll use an overload of the Html.Partial helper, which accepts a second parameter.
Normally when you call the Html.Partial helper, it just gets a reference to the same model object that the view has,however, this overload allows me to pass in any object that I want to use as the model. In this case, I'm passing in the single post object, not the entire collection and that's all the changes that I need to make to the view. Now, let's jump to the controller and populate the model so that we can run this and see it in action. On my landing page in my index view, I need to create an array of posts to populate the model that our view expects.
So I'll just make a few copies of the dummy post object that I've already created. Then I'll pass that array to the view and run the site to see all of this in action and that's it, that's how you reuse markup across your site with partial views.




Reuse view logic with injectable services



By this point in the course, I've shown you several different HTML helper methods, and you've accessed these helpers from the special HTML and URL properties in the View. And trust me, the more you use ASP.NET Core MVC, the more you're going to want to create your own helpers and custom properties, and in this video, that's exactly what I'm going to show you how to do. For a good example of the need for a custom helper method, take a look at how we're rendering the Posted.Date property. When we leave it up to Razor to render it, it ends up displaying some long string with the time, including seconds and everything.
But, what if we only wanted it to display the date? We could change the code in this one place to make that happen. And that's all well and good, but what if we applied this approach all over our application? And then we wanted to change the way that we displayed all of our dates, wherever they're rendered? Well, then we'd have to search for all those referencesand update them everywhere in our application individually. Wouldn't it be nicer if we just centralized this formatting logic in one place? Well, custom helper methods to the rescue.
First, we'll create a new class to hold this logic. I'll call it FormattingService and put it in the Models folder. Then, I'll create a new Method in this Class named AsReadableDate, and execute the same logic as in our View to render the custom date string. Next, I'll jump back to my View, and register this new Class as a Property in the View by using the @Inject keyword at the top of the View, specifying two parameters separated by spaces.
The first parameter is the Type that should be injected, and the second parameter is the name of the Property that we want MVC to create for us dynamically. With this line in place, I can then refer to this Format property and use the AsReadableDate method that it exposes instead of the two string call that we currently have. And, notice as I type, how I get full IntelliSense as I reference this Property. Now that I've added my new Property and begun using it, I'm almost ready to run my application, but here's what would happen if I ran it now.
Now we've seen this page before, because this technique leverages ASP.NET's built-in dependency injection framework,and as I demonstrated earlier, that framework doesn't like it when you ask for Types that it doesn't know about. So we have to register this Type before we can start using it. To do this, simply jump to the Startup class, and add a registration line in the ConfigureServices method, just like the lines we added previously to register the FeatureToggle class. And with this last piece of the puzzle in place, we can finally see the injected Property in action.
Just refresh the page, see the error go away, and the blog post displayed with that nicely formatted text for the date. Now, changing the date formatting across the entire site is as simple as changing one Method. And that is how you add your own properties to your Views using the technique called Injectable Services.





Reuse application features with view components



 Earlier in the course, I demonstrated two concepts which at the time, probably seemed completely unrelated,dependency injection and partial views. However, put them together and they become a powerful way to reuse both logic and views, known as view components. View components provide you with an easy, and convenient way to both execute logic, and render the result all with one call to a single HTML helper. To find a good example of a scenario when a view component would be helpful, we have to look no further than the homepage of our sample application.
See the section labeled monthly specials in the left hand column, that section is currently just hard-coded HTML in our layout, but if it had a real implementation, it would involve going to the database and grabbing the latest monthly specials.Since this markup is in our layout, every single action that implemented that layout would have to know how to get those monthly specials, which would be terribly hard to maintain, not to mention a huge violation of separation of concerns. To fix it, let's encapsulate all of that logic in a view component.
Since a view component consists of both a view, and a class that contains the corresponding logic for that view, we'll need to create both of those things. The view component class is the most important part because that's the artifact that ASP.NET Core MVC looks for in order to find out about your component. So we'll begin by creating that first. To do that, simply create a folder named view components in the root of your application. Note that like the controllers folder, and the models folder that we've created, you can name this folder anything you like, ASP.NET Core MVC doesn't care.
Then we can add a new class to this folder named MonthlySpecialsViewComponent. Although ASP.NET Core MVC does not care about the name of the folder that your component lives in, it does require at least one of the following things to be in place in order to recognize a class as a view component. The first requirement is that the name of the class ends with the suffix view component. We've named our class MonthlySpecialsViewComponent, so we've satisfied that criteria already. The second criteria could be that the class is decorated with the view component attribute, or the third criteria is that the class can extend from the view component base class.
Here I've shown every single one of these three requirements applied which will work just fine, but when you do it yourself, you really only need to pick one of these three things. Any one of them will work. With at least one of these three requirements met, ASP.NET Core MVC will now be able to discover our view component. The only thing left is to implement it. When the component is invoked MVC looks for a public method on the component class named invoke that accepts the same number of parameters that the component was invoked with, and it returns an instance of I ViewComponent result.
Our component won't accept any parameters, so our invoke method will look like this. Just to get this working, I'll just return a default view with a simple call to the view method on the view component base class. Though this isn't the same exact view helper method that's available on the controller base class, it's implemented to work in just the same way. We'll come back and populate this method with some real logic in just a few minutes, but for now, let's jump right in, and invoke this new class.
To do that, just use the component.invoke helper method in the view that you wish to render the view component in. Since I want to render this view component in the layout of the site, I'll open up the layout view, find the monthly specials section, and I'll make a copy of the HTML to save for later. In its place, I'll make a call to the Component.InvokeAsync method, passing in the name of the view component that I just created, MonthlySpecials, and since this is an Async method that we're calling from a view, I'll have to put the await keyword in front of it in order for it to work.
As an alternative, I can also use the generic version of the InvokeAsync method to make a strongly typed reference to the view component. Notice how I've wrapped the call in parenthesis, so Razor doesn't confuse the generic parameter within HTML tag. Now it's time to create the view for this new View Component, but the question is where should the view live?To this point, I've shown you how to put controller views in folders named after the controller they are created for, and I've shown you how to use the shared folder to share views between controllers, however, view components are not controllers, and MVC searches for view component views in a different place.
To find out where to look, let's just run the application, and let MVC tell me. From this error message, I can see thatASP.NET Core MVC is attempting to locate a view named default.cshtml in one of two folders. Each of these folders ends with the path /Components/ the name of the view component, in this case, Monthly Specials. Interesting enough, ASP.NET Core MVC will allow us to place the view for this component underneath either the controller folder or the shared folder.
I'm only going to create one view in this course, but the fact that MVC looks in both the controller and the shared folder path means that you can actually create controller specific versions of your view component views if you like. Okay, now that we know where to put it, let's create that new view. I'll start by creating that new folder in the shared folder path that ASP.NET Core MVC is telling me about, /views/shared/components, and then under that folder, I'll create a new folder with the same name as my component, and then I'll create a regular new ASP.NET Core MVC view named default.cshtml.
Once I have that, I can paste that hard-coded markup that I just copied from the layout file a minute ago. Now that I've created the view, I should be able to run the site, and see the view component in action. Technically speaking, that's all you need to do in order to create a view component. However, in order to show off the real value of view components, let's enhance this demo a little bit.




Comments