ASP.Net 如何在不重定向视图的情况下调用控制器中的方法

问题描述

我有一个视图,显示指定文件夹中的每个文件名称旁边的删除按钮。我希望用户能够单击按钮,从文件夹中删除文件,然后使用更新的文件列表刷新页面

Index.cshtml


@{
    ViewBag.Title = "Index";
}

@{
    var arrayOfDocs = ViewData["arrayOfDocs"] as string[];
}

<h2>Case Log Documents</h2>

<table class="table">
    <tr>
        <th>
            Files
        </th>
        <th></th>
    </tr>

    @foreach (var item in arrayOfDocs)
    {
<tr>
    <td>
        <a href="~/Case_Log_Docs/@item">@item</a>
    </td>
    <td>
        @Html.ActionLink("Delete","Delete",new { fileName = item })
    </td>
</tr>
    }

</table>

通过这一行,我试图在我的控制器 @Html.ActionLink("Delete",new { fileName = item })调用 Delete 方法。但是,操作链接将我重定向删除页面(它不存在,也永远不会存在)。我想要发生的是调用删除方法,然后刷新我所在的页面

控制器

   [HttpPost]
        public ActionResult Delete(string fileName)
        {
            try
            {
                string path = Server.MapPath("~/Case_Log_Docs/");
                string fullPath = path + fileName;
                if (System.IO.File.Exists(fullPath))
                {
                    System.IO.File.Delete(fullPath);
                }

                return RedirectToAction("Index");
            }
            catch
            {
                return View("Index");
            }
        }

我该如何设置才能做到这一点?

解决方法

听起来好像没有找到路线。您有几件事情要做。

首先,您已使用 POST 动词将您的方法标记为接受 Http 请求:

[HttpPost]
public ActionResult Delete(string fileName)

这意味着来自前端的请求需要使用 POST 作为动词才能正确路由。正如@jackdraw 在他的回答中提到的,您需要使用一个表单来完成此操作。或者,您可以发布 Ajax 帖子,但该选项似乎超出了您的问题范围,因此请用表单标记将表格括起来。您尚未提供控制器的名称,因此我将使用占位符:

@using (Html.BeginForm("Delete","NameOfControllerWithDeleteMethod"))
{
    //Put your table here
}

您还需要一个字段来保存要删除的内容的标识符。在这种情况下,文件名本身:

@using (Html.BeginForm("Delete","NameOfControllerWithDeleteMethod"))
{
    <input type="hidden" id="fileName" name="fileName" />
    //Put your table here
}

然后,您需要使用要删除的文件的名称填充此字段。您可以在删除按钮的 Click 事件上执行此操作。将您的操作链接替换为 submit 类型的输入并使用 JS 进行设置。在你的循环内。注意JS字符串和Razor代码的插值:

@foreach (var item in arrayOfDocs)
{
<tr>
<td>
    <a href="~/Case_Log_Docs/@item">@item</a>
</td>
<td>
    <input type="submit" value="Delete File" onclick="document.getElementById('fileName').value = '@item';" />
</td>
</tr>
}

最后,在您的控制器的 Delete 方法中,无论您是否遇到错误,您都希望在两种情况下都重定向回原始的 Index 方法。您可以使用临时数据集合来回传一条只显示一次的消息:

try
{
    string path = Server.MapPath("~/Case_Log_Docs/");
    string fullPath = path + fileName;
    if (System.IO.File.Exists(fullPath))
    {
        System.IO.File.Delete(fullPath);
    }

    TempData["UserMessage"] = "Success!";
    return RedirectToAction("Index","NameOfControllerWithIndexMethod");
}
catch
{
    TempData["UserMessage"] = "Something went wrong... :-(";
    return RedirectToAction("NameOfControllerWithIndexMethod");
}

在您的视图中收集此数据并将其显示在某处:

@{ var userMessage = TempData["UserMessage"] as string; }
@if(!string.IsNullOrWhiteSpace(userMessage))
{
    <div class="some-message-style">@userMessage</div>
}