Francis Rodgers Francis Rodgers - 1 year ago 61
C# Question

Exception handling for file deletion and showing a message using ValidationMessage()

This question continues from a previous question I posted at the link below:

C# MVC based CMS problems deleting file

In summary: I am trying to delete a file. I now have all the necessary functionality working thanks to the answer at the above post. However, occasionally, if the file was in use (which would happen if I downloaded the file prior to deleting for example), I would get an IOException.

I want to handle this exception and display a message back to the user when this happens.

I tried debugging the jQuery code, but whenever I put a breakpoint on it, I start skipping through 1000's of lines of jQuery libraries. So as a quick alternative I just put alerts everywhere.

I discovered that most of this code is not being executed - so I put comments beside where I think I should be seeing messages but am not. So as a result I am unable to debug or figure out what the code is supposed to be doing.

So my first question is how to get the exception showing. It seems that even though this is Ajax, the whole page still refreshes, which to me is not the expected behaviour for Ajax calls (so if an error is showing its maybe lost when the page refreshes). However, with all the alerts, I should see the error somewhere, but I am not. I have purposefully altered the working code to always throw an exception for now. Again, the delete functionality works, its the error reporting that fails.

My next question is to have a brief explanation of why each section of the code (where highlighted) is needed as I don't know why those sections exist and I cant figure it out because I cant debug into or show alerts for them.

Below is the index view and the code in question:

@model IEnumerable<FileInfo>

ViewBag.Title = "File List";


<p>@Html.ActionLink("Upload", "Upload")</p>
<p>@Html.ValidationSummary(true, "", new { @class = "text-danger" })</p>
<p>@Html.ValidationMessage("Name", new { @class = "text-danger" })</p>
<span class="message text-danger"></span>
<table class="table">
<th>File Name</th>

@foreach (FileInfo file in Model)
<form class="deleteform">
<input type="hidden" name="fileName" value="@file.Name" />
<input type="submit" value="delete" />
<td>@Html.ActionLink("Download", "Download", new { fileName = file.Name })</td>

@section Scripts {

<script type="text/javascript">
var url = '@Url.Action("Delete", "FileManagement")';

$('.deleteform').submit(function ()
alert(".deleteform.submit entered...");//This alert shows

return confirm("are you sure ...");//This alert shows

var formData = $(this).serialize();
alert(formData);//This does NOT show.

var row = $(this).closest('tr');
alert(row);//This does NOT show.

$.post(url, formData, function (response)
alert("$.post() entered...");//This does NOT show.
alert(response);//This does NOT show.
if (response)
alert("response true");//This does NOT show.
alert(response);//This does NOT show.
//row.remove(); //This code actually works even though the alert above does not show.
} else
alert("response false");//This does NOT show. - I dont know what this section of code is for.
//alert("Error 1 - display message");
// Oops - display message?
alert("$.post() finished...");//This does NOT show.

}).fail(function (response)
alert("$.fail() entered...");//This does NOT show. - I dont know what this section of code is for.
alert("Error 2 - display another message");//This does NOT show.
// Oops

alert("$.fail() finished...");//This does NOT show.
return false; // cancel the default submit

alert(".deleteform.submit finished...");//This does NOT show.

Below is the controller for this view and the delete actions:

public ActionResult Index()
DirectoryInfo dirInfo = new DirectoryInfo(Server.MapPath("~/UserFiles"));
List<FileInfo> files = dirInfo.GetFiles().ToList();

return View(files);

public ActionResult Delete(string fileName)
var path = Path.Combine(Server.MapPath("~/UserFiles"), fileName);

if (System.IO.File.Exists(path))
throw new IOException("Hello - Test Message...");
catch (IOException e)
Response.StatusCode = 500;
Response.StatusDescription = e.Message;
//ModelState.AddModelError("Name", e.Message);
return Json(null);
//return HttpNotFound();

return Json(true);
//return RedirectToAction("Index");

I would appreciate any help on this.

Answer Source

You cannot use return confirm("are you sure ..."); in the .submit() handler because it either returns false which cancels everything, or it returns true in which case you will be making a normal submit. In either case, it exits the function.

You need to change the script to

$('.deleteform').submit(function () {
    if (confirm("....") {
        // make you ajax call here
    return false; 

You also need to modify your controller code. Currently your last line (return Json(true);) can never be executed, and the code in the if block is always returning an error, so will always go to the .fail() function. Generally, you should not return the specific details of exceptions your code throws (this just exposes it to malicious users) and it is better to return a more general error, or return null and hard code the error message in the script. There are various ways you can handle this, including

   // delete the file
   return Json(true); // to indicate success
catch (.... )
    return Json(null); // indicate failure

which in the script means

if (response) { // this will be executed if you returned true
    ... // delete the row
} else { // this will be executed if you returned null
    ... // display a message to the user

and the .fail() function will be executed if an exception is throw on the server which you have not caught.

Alternatively you could return on object with properties for Success and Message which gives you a bit more control over the message, for example

return Json(new { Success = true });
// or
return Json(new { Success = false, Message = "The file does not exist"});
// or
retrn Json(new { Success = false, Mesage = "The file is in use, please try again late" });

and the in the script

$.post(url, formData, function (response) {
    if (response.Success == 'False') {
        var message = response.Message; // display it
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download