ASP.Net 如何在不重定向视图的情况下调用控制器中的方法
ASP.Net how to call a method in a controller without redirecting the view
我有一个视图显示指定文件夹中的每个文件,名称旁边有一个删除按钮。我希望用户能够单击按钮,从文件夹中删除文件,然后使用更新的文件列表刷新页面。
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>
通过这一行,我试图在我的控制器中调用 Delete 方法 @Html.ActionLink("Delete", "Delete", new { fileName = item })
。但是 link 操作将我重定向到删除页面(该页面不存在,也永远不会存在)。我想要发生的是调用 '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 post 但该选项似乎超出了您的问题范围,因此请将 table 包含在表单标签中。您还没有提供控制器的名称,所以我将使用占位符:
@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
事件上执行此操作。将您的操作 link 替换为类型 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>
}
我有一个视图显示指定文件夹中的每个文件,名称旁边有一个删除按钮。我希望用户能够单击按钮,从文件夹中删除文件,然后使用更新的文件列表刷新页面。
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>
通过这一行,我试图在我的控制器中调用 Delete 方法 @Html.ActionLink("Delete", "Delete", new { fileName = item })
。但是 link 操作将我重定向到删除页面(该页面不存在,也永远不会存在)。我想要发生的是调用 '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 post 但该选项似乎超出了您的问题范围,因此请将 table 包含在表单标签中。您还没有提供控制器的名称,所以我将使用占位符:
@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
事件上执行此操作。将您的操作 link 替换为类型 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>
}