3.4 Editing Soundboard Messages
We can create posts in our app, but we also need to be able to edit them. In this lesson, we'll sketch out the
Edit method that allows users to edit post data.
1.Introduction1 lesson, 01:12
2.Getting Started2 lessons, 22:54
3.Request Handling5 lessons, 1:06:56
4.Displaying Data5 lessons, 1:15:23
5.Conclusion1 lesson, 00:39
3.4 Editing Soundboard Messages
Editing a message is very similar to creating a message. The forms are going to be similar, and in fact the code inside of the controller is going to be similar as well. The main difference, however, is how we access these resources. For example, if we want to create a message, we go to /message/create. And then that takes us to the form, we fill it out, we submit it. And that post request is going back to message/create. But what about editing? Well, it could look like this. We of course want message, but then we could have a resource called edit. But here's the thing, we need to know what message that we want to edit. Well, every message is eventually going to have an ID. Now this isn't part of our model yet, but whenever we start adding the code necessary for storing our messages in the database, we will eventually have an ID. So we could have message/edit, and then we could have the message-id. And then that will take us to a form where the message is automatically populated in the form. We can update that message and then submit the form to this same resource. So if a resource in our application is a method on a controller, how then do we write the method for this request? Well, the name is going to be edit. That's fairly obvious, but how do we get the message-id? Well, in order to answer that question we need to look at our routing table. So, let's go to our project, and let's open up the Startup class. And let's look at the configure method because that is where the routing table is configured. Down here at the bottom, we see this app.UseNvc, and we have this routes object. This is the routing table, and the routing engine is going to take a request. And it's going to look for a match in the routing table. And it's going to do so based upon the URL. So here we have just one entry in our routing table. It's called default, and it has this template. This is the template of the URL that the routing engine is going to try to find a match for. So here we have controller, action, and id. And these values are surrounded by curly braces. These are placeholders. And the routing engine is going to take each segment of a URL and plug it in for these values. So let's say that we make a request for our message and then create. So it's going to take the first segment which is message, and it's going to plug that in as the controller. It's going to take create, and then it's going to plug that in as action. But then notice that there's this id segment, and it has a question mark. This is an optional segment. So a URL coming in with two or three segments is going to match this template. And the routing engine is going to send that request to the message controller and the create method on that message controller. So let's look at our example. We want a URL for editing a message. Well, we would have message and then edit and then id. So the routing engine is going to take this request. It's going to find a match with our default route. Because it has three segments, the first is message. It's going to map that to controller. The second is edit. It's going to map that to action. The third is a value, and it's going to map that to the id. So it's going to create, the message controller is going to try to find a method called edit. Now one does not exist right now, so we would get a 404. Because that action method doesn't exist, the resource doesn't exist. But whenever we write the edit method, it will call the edit method and pass in the id as an argument to that method. So, all we really need to do is write two methods, one that is going to get requests. So let's go ahead and write that. Let's start with our HttpGet attribute. Then we want public IActionResult, and we'll call it Edit. We want to get the id of the message, so we will accept an integer value. And then we will retrieve the message from the data store, which we don't have yet. And then we will pass that message onto the view. But what about a post request? Well, let's write the method first. So, public IActionResult Edit and id, but we also want to pull in the information from the form. And ideally we would want to use the same type of model binding that was used for the Create method. And thankfully, we can. All we have to do is add another parameter here. So the first is the id which the routing engine is going to pull from the URL. The second is going to be the Message that's going to come from the form. And we will just call that model. Well let's start to flush this code out so that whenever we finally have the code for retrieving and updating and storing data, then we can just plug that in. And we will have most everything else already done. So inside of the Edit method for get requests, we want to take this id, and we want to find the message with that id. So let's add a todo, and we will say retrieve message. Now let's go ahead and create a message object because we need to do something in here. If the message with this id doesn't exist, well, then we want to say that it doesn't exist. So let's new up Message, and let's add an if statement. If message == null, then that is not found. So we will simply return HttpNotFound, and that will give the user a 404. Now if we do have a message, well, then we just want to return the View, passing in our message. And that's really all that we need to do here for the get request. The post request is going to be a mix between the Edit and the Create method for post requests. Now let's go ahead and let's copy this ValidateAntiForgeryToken attribute. Because this is a post request, we want to validate that token. So we first of all need to retrieve the message from the data store. Because we have that id, we want to ensure that this is the message that we are editing. So we have our todo message once again. We also want to check to see if message is null. Because if it is, then there's nothing to do. This message doesn't exist. But beyond that, we want to do what we did inside of the Create method. We want to check to see if the ModelState IsValid, and if not, we will return the View, passing in the model. And then we will store our new message, and then we will redirect to probably the index action. So the remainder of this method is going to be almost exactly like the Create method. However, instead of store, we can say update and store. And, we can actually write that code. We can say message.MessageTitle = model.MessageTitle, and then, essentially the same thing for the content. So, let's just copy and paste, and then make the necessary changes. And now all we need is the view for this edit action. So let's go to the Views folder > Message. And let's take the CreateView. Let's copy and paste that, and let's rename the copy to edit. Now, there are going to be some changes that we are going to make. And a lot of them are going to be removing the HTML helper code. So let's get rid of the AntiForgeryToken. Let's also get rid of the ValidationMessages. So both of them, one for the MessageContent, the other for the MessageTitle. We will leave the summary at the top, but the individual messages can go away. And let's also use the new tag helper for the MessageTitle, instead of the HTML helper. So let's just copy what we have for the content, and then change the asp-for attribute to MessageTitle. And then one other thing, let's get rid of the action attributes because we are going to use the tag helper to generate the necessary action attribute. So the first thing we need to do is tell this form what controller that we want to use. And that is with the asp-controller attribute. And here we want to go to the message controller. Now we don't put on the whole name of the controller. We just use the short name, message, and it will automatically use the message controller. The next is the action. So that is asp-action, and this is method name that we want to use, edit, in this case. And we can also specify the anti-forgery token. There is asp-anti-forgery, and we set this to true so that we will use the anti-forgery token. And that's it, that is a nice and clean view. There's no weird @ signs except up here at the top, and everything else just looks nice. The only other things that we need to change is the value of our button, let's change that to Edit Message. Let's also change the title to Edit Message, and then we would do the same for this h2 element, so just Edit Message. Well let's run this. I'm going to use Ctrl+F5, and we won't submit the form. But we'll at least go to the form and inspect the HTML. So let's do message and then edit and then 1. It really doesn't matter what the ID is. And then we have our Edit Message form. Now, if we had actual data for our message, we would see that here in the form. And I guess we can go ahead and do that. Let's go back to our message controller and in the Edit method for get requests, lets just go ahead and initialize these properties with something. So lets set the title equal to, A sample message. And then for the content, we can do something like, This is the content. And then we will see these values in the forms. So we can go back to the browser. We can refresh, and then we will see the content. Let's look at the source. And we can see the generated HTML. So here we have our form. The method is of course post. We left that attribute in our HTML. But then notice that we have this action, and that was generated appropriately, message, edit, and 1. And then we have all of the other stuff that we had before, but now we also have the RequestVerificationToken. So that whenever we submit the form, that can be validated, and we are protected from cross site request forgery attacks. Well, in the next lesson we're going to take the next step, and actually start storing data in the database.