异常处理文件删除和使用ValidationMessage()显示消息

本文关键字:显示 消息 ValidationMessage 文件 删除 异常处理 | 更新日期: 2023-09-27 18:05:53

这个问题是我之前发布的一个问题的延续:

将文件名传递给视图

总结:我正在尝试删除一个文件。多亏了上面帖子的答案,我现在已经有了所有必要的功能。然而,偶尔,如果文件正在使用中(例如,如果我在删除文件之前下载了该文件,就会发生这种情况),我会得到IOException。

我想处理这个异常,并在发生这种情况时向用户显示一条消息。

我试着调试jQuery代码,但是每当我在上面放一个断点时,我就开始跳过1000行jQuery库。因此,作为一个快速的替代方案,我只是在各处放置了提醒。

我发现大部分代码都没有被执行——所以我在我认为应该看到消息但没有看到的地方加上了注释。因此,我无法调试或弄清楚代码应该做什么。

所以我的第一个问题是如何得到异常显示。似乎即使这是Ajax,整个页面仍然刷新,这对我来说不是Ajax调用的预期行为(因此,如果显示错误,则可能在页面刷新时丢失)。然而,有了所有的警报,我应该在某个地方看到错误,但我没有。我有目的地改变了工作代码,现在总是抛出异常。同样,删除功能是有效的,是错误报告失败了。

我的下一个问题是简要解释为什么需要代码的每个部分(突出显示的地方),因为我不知道为什么这些部分存在,我无法弄清楚,因为我无法调试或显示它们的警报。

下面是索引视图和相关代码:

@model IEnumerable<FileInfo>
@{
    ViewBag.Title = "File List";
}
<h2>Index</h2>
<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">
    <tr>
        <th>File Name</th>
        <th>Actions</th>
    </tr>
    @foreach (FileInfo file in Model)
    {
        <tr>
            <td>@file.Name</td>
            <td>
                <form class="deleteform">
                    @Html.AntiForgeryToken()
                    <input type="hidden" name="fileName" value="@file.Name" />
                    <input type="submit" value="delete" />
                </form>
            </td>
            <td>@Html.ActionLink("Download", "Download", new { fileName = file.Name })</td>
        </tr>
    }
</table>
@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
    <script type="text/javascript">
        $(document).ready()
        {
            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.
            });
        }
    </script>
}

下面是这个视图的控制器和删除操作:

    public ActionResult Index()
    {
        DirectoryInfo dirInfo = new DirectoryInfo(Server.MapPath("~/UserFiles"));
        List<FileInfo> files = dirInfo.GetFiles().ToList();
        return View(files);
    }
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Delete(string fileName)
    {
        var path = Path.Combine(Server.MapPath("~/UserFiles"), fileName);
        if (System.IO.File.Exists(path))
        {
            try
            {
                //System.IO.File.Delete(path);
                throw new IOException("Hello - Test Message...");
            }
            catch (IOException e)
            {
                Response.StatusCode = 500;
                Response.StatusDescription = e.Message;
                //ModelState.AddModelError("Name", e.Message);
            }
        }
        else
            return Json(null);
        //return HttpNotFound();
        return Json(true);
        //return RedirectToAction("Index");
    }

异常处理文件删除和使用ValidationMessage()显示消息

您不能在.submit()处理程序中使用return confirm("are you sure ...");,因为它要么返回取消一切的false,要么返回true,在这种情况下您将进行正常提交。在任何一种情况下,它都退出函数。

您需要将脚本更改为

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

你还需要修改你的控制器代码。目前,您的最后一行(return Json(true);)永远无法执行,并且if块中的代码总是返回错误,因此将始终转到.fail()函数。一般来说,您不应该返回代码抛出的异常的具体细节(这只会将其暴露给恶意用户),最好返回更一般的错误,或者返回null并在脚本中硬编码错误消息。有很多方法可以处理这个问题,包括

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

在脚本中表示

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
}

.fail()函数将被执行,如果在服务器上抛出一个您没有捕获的异常。

或者你可以返回具有SuccessMessage属性的对象,这给了你对消息的更多控制,例如

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" });

和脚本中的

$.post(url, formData, function (response) {
    if (response.Success == 'False') {
        var message = response.Message; // display it