HTTP DELETE
Finally, we need a way to get rid of uploaded images. For a couple of reasons, I think the only right way to do this is to use the HTTP DELETE method instead of some remote procedure call:
- It's awkward to create a resource containing the word delete for the sole purpose of removing another resource.
- We can call the DELETE method without much effort.
Let's look at the code flow for deleting an image from our application. Instead of acquiring the request stream or anything else, we rely on the Silverlight-JavaScript integration to get things done. When the user clicks the Delete Image button, we call a JavaScript function and remove the image from the list:
private void DeleteImages_Click(object sender, RoutedEventArgs e) { if (grdDetails.DataContext != null) { ImageItem item = (ImageItem)grdDetails.DataContext; HtmlPage.Window.Invoke("DeleteImage", item.ImageId); ImageDocument.RemoveAt(lstImages.SelectedIndex); grdDetails.DataContext = null; } }
The JavaScript DeleteImage function lives on the same page as the Silverlight control:
<script type="text/javascript"> function DeleteImage(imageId) { PhotoWebXHR.Delete(imageId); } </script>
The PhotoWebXHR.Delete function then instantiates an XMLHttpRequest object by using a special helper type, XHRCreator. XHRCreator is a utility class I wrote that handles differences between browsers, while still yielding a good XMLHttpRequest object. (The source code for this article includes a copy of XHRCreator.) The code sends a message over to the GAE endpoint to delete the specified image. The URL handling the DELETE is the same URL you would use to view the image's picture.
var PhotoWebXHR = { Delete: function(id) { var xhr = XHRCreator.CreateRequest(); if (xhr != undefined) { xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { } }; xhr.open("DELETE", "/img?id=" + id); xhr.send(null); } } };
At the server, the delete code looks up the image and verifies that the current user owns the image. If so, the delete process continues:
def delete(self): currentUser = getCurrentUserOwner() if not currentUser is None: requestedImage = db.get(self.request.get("id")) if requestedImage.owner.key() == currentUser.key(): db.delete(requestedImage)
The previous JavaScript function does nothing with the OK response from this method.