4.3 Final Steps
We're almost done! We have just a few things to implement and fix before our application successfully runs on the web. In this lesson, I'll show you how to complete the application functionality.
1.Introduction1 lesson, 01:40
2.Get Started2 lessons, 11:54
2.1What You Need05:38
2.2How GitHub Webhooks Work06:16
3.Build the App4 lessons, 56:39
3.1Start the Project11:06
3.2Secure Our Webhook15:21
3.4Build a Custom Configuration12:59
4.Display Content3 lessons, 38:55
4.1Parse the Documents10:21
4.2Display a List of Posts14:54
5.Conclusion1 lesson, 01:10
4.3 Final Steps
We're just about done with our application. We are displaying all of our posts, but we need to display a single post as well. So we're going to do that in this lesson, and then we are finally going to publish it and see if it actually works. So we're going to start in our BlogController. We have the index action method for displaying our list of posts. Now we want one for a single post. So we're going to have a method that returns an IActionResult, and let's just call this SinglePost. Now typically, the URL has three things. It has the year, month, day and then the name of the post. So we will do the same thing here. So we will have year, month, and day, and then finally the title. And then we also need to set up the route as well. So, let's use the route attribute. We will have the controller here, and then we will have int, I'm sorry not int. We will have year, followed by month, and then day, and then finally the title. Now, inside of this method we need to build the file name. So let's make that the first thing that we do. We'll save our path and we're going to make this a verbatim string. Now the base path is our www root and then the posts. So we need the year first, and then we need the name of the file. So we have year followed by year, and then month followed by day and then the title. Now we don't need to worry about the extension, because the repository is going to handle that for us. So this our file name. We'll then save our post = _posts.GetPost(path), and then we need to check to see if we have a post. Cuz if we don't, then we want to return HttpNotFound. Otherwise, we will return the view and we will pass in the post as our model. So that's pretty straightforward. Let's create that view. So we'll go down to the views folder, let's copy what we have for the index view, and we will change that to single post, and our model is not going to be an i enumerable of post. It's simply going to be a post. We'll get rid of the for each loop because we don't have anything to iterate, and then we will just change the at post to at model, and that is going to be it for this view. Now, we do need a link in our list, so that we can get to this view. So let's go to the index view, and I'm going to cheat and paste this in because it's quite a bit of typing, and quite a bit of repetition, but it is straightforward. I am using the new tag helper feature in MVC 6. I've set asp-action to SinglePost. I've set asp-controller to Blog, and then I've set the route values. I have asp-route-year, I have asp-route-month, day, and title. Now, year, month, day is set to year, month, day of the publish date, and then title takes the posts title, it lower cases it, and then replaces all of these spaces with a hyphen. Now, that's now going to work in every case especially if the title has some special characters in it. So, this is not something that we would use in a real world application. Ideally, we would have the final name associated with our individual post, but for the time being we're just going to leave this as is and as simple as it is. Okay, so we have everything in place. Let's run it and let's see what happens. So whenever our application is up and running we will need to go to /blog, so that we can then click on our links. Hopefully our links are there. They are and it looks like that they are being generated correctly. So let's click on this and we get a 404, so something obviously went wrong. Let's debug. Let's go to our blog controller and let's set a break point here on line 32, and then we will refresh, and then we will just step through our code. Although my keys aren't working so we're going to use the button bar. So we're going to step over that. Let's see what the path is and that is the correct path so let's step into the get post and we will see what happens here. Now we are reading the file and that's the problem. Our path is just the relative path. It's not the full path. So let's go ahead and stop here, because that's pretty much where the problem is, and we have one of two choices. This is in the PostRepository. We do have access To the basePath. So we could just set up our GetPost method in order to get the path with our basePath, or we can modify the FileStore class. Since we're here, let's just do it this way. Let's add private readonly string and we'll have _basepath, and then in the constructor we'll say _basepath equals to this value that we passed to the file store constructor. That will be our base path which we will then pass to our file store, and then we can use that down here in get post. So we can save our file name equals and we will essentially do the same thing that we have done before. We will build our path using our base path\ and then path, and since we already are building our path here and it's the complete path we'll just go ahead and add the extension here. That way we don't have to do it again, and that should fix that. So let's run the application again although we do have a break point still on the blog controller. Let's go ahead and clear that, because I'm pretty sure that our problem will be fixed. So let's once again go to /blog. Let's click on one of these links, and we are taken to the individual post page. So that is working. All we need to do now is publish it. We need to set up our web hook and then actually test if this is going to work. Now, I'm going to publish this to Azure. I'm going to go to build And then publish git powered and then I'm going to choose Microsoft Azure App Service. Now you do need to have an Azure subscription in order for this to work, but subscriptions are free. It's not until you start using some of the more advanced features that you have to pay for things. So I have a BizSpark subscription, and I'm going to create a new web app. I want to call it GitPowered, and I will need to select my service plan. I don't need a database server, and I'm just going to click on Create. So we're going to see if this is indeed going to work, and first this is going to create the website, and then it probably will prompt me for the publishing settings, and here they are. Now if we were able to debug these applications through Azure, then we can come to configuration and we can change that to debug, but we can't do that with ASP.NET 5 applications yet. It works for the prior versions, but just not ASP.NET 5 yet, so it's a pretty cool feature unfortunately we can't take advantage of it right now, and then we are just going to publish. After the publish completes we can go gitpowered.azurewebsites.net just like you see here, and we can go to blog and hopefully well, we see an error. And I was gonna say hopefully we wouldn't see anything but the header, but we do have an error, so let's see if I can figure out what that is real quick and then I will republish, and then we will go from there. So, let's go to the data folder and let's look at the FileStore. Okay, so if we get all of the files, and it's going to call GetFilesInternal, and if the path doesn't exist, then we could get an exception. Okay, so if Directory.Exists, rather if it doesn't exists, or rather if it doesn't exist, then we want to return an array with no elements. So, you'll pass in path here, and we will return_new string. So let's try that again. I'm going to publish, we'll go back to blog, and we'll see if that works, and that was the problem. We don't see anything here and that is exactly what we should be seeing. So now we need to go GitHub, and we need to set up our webhook. And in you repository settings you will want to go to webhooks and services, click on Add webhook and then for the payload URL mine is http://getpowered.azurewebsites.net/api/p- ushwebhook. Now the content type is application json. We do need to set up our secret, and that is ducks fly with geese although I like to see what I'm typing, so let me type this in Notepad, ducks fly with geese. We'll copy that, and then paste it into our secret. We want just the push event, and then this is active. So, we will add the web hook. So everything is setup. Now, we should be able to commit and push to our repository and everything should work. I created a new file. Today is New Year's day, and I'm going to commit this. So new year's post, and we will commit, and then we will push to GitHub. Hopefully, everything is going to work just fine. Now, we're not going to see anything happen as far as our webhook is concerned. It's just going to send that request, and we're going to wait for a couple of seconds, and we will go back to our website, and hopefully we will see something here in our blog list. Unfortunately it didn't work, and in fact there were a variety of reason as to why it didn't work, but I will walk you through them. The first is the BaseDownloadUrl. The repository was still pointing to the old repository, so I had to change it to gitpowered. So that was the first problem, and if you look at the webhook settings you can see the recent deliveries, and it will tell you whether or not the delivery was successful, or whether or not it failed, and it will tell you. In this case it says that the response is 400, and it will also show you the response. Now, the seconds problem was that the x-hub-signature header included sha1= and then the hash, and if you remember we didn't check for that. We were just checking for the hash. So I had to modify the code in order to do that and that was inside of GitHub validate. So whenever we compute the hash it now tacks on sha1= and then the hash, so that it can be properly compared to the signature. So that was the second problem. The third was that whenever I created the file, and committed and push it it was not inside of the posts folder. I had just created the year 2016, added the file inside of that and then pushed. Now remember that we were looking for the posts folder as well, so I had to change that, and I sent another push request, but that didn't solve all the problems. The final problem was the name of the file, so if we go and look at BlogController. See it's going to take the year, the month, and the date, and it's going to take those exactly as they are, and it's going to create the path to that file. Well the file name has two digit month and two digit day values, so it was not able to find the file. So I had to modify this so that it will always output a two digit month and day when it generating the path to that file, and then once I published all of those changes finally we see that it works. We can click on the link to take us to that page, and we see that post. So there you have an application that relies upon a GitHub repository as the datastore, and despite all of the speed bumps it's still a pretty awesome thing.