ASP.Net how to call a method in a controller without redirecting the view

I have a view that displays every file that is in a specified folder and a delete button beside the name. I would like for the user to be able to click the button, delete the file from the folder, and then the page refresh with the updated list of files.

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>

With this line I am trying to call the Delete method in my controller @Html.ActionLink("Delete", "Delete", new { fileName = item }). However the action link redirects me to a Delete page (which does not, and will not ever exist). What I want to happen is to call the ‘Delete’ method and then refresh the page I am on.

Controller

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

How can I set this up to do that?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

It sounds to me like the route is not being found. You have a few things to work on here.

First, you have marked your method as accepting Http requests with the POST verb:

[HttpPost]
public ActionResult Delete(string fileName)

This means the request coming from the front end needs to use POST as the verb in order to be routed appropriately. As @jackdraw has mentioned in his answer, you need to use a form in order to accomplish this. Alternatively, you can do an Ajax post but that option seems to be beyond the scope of your question, so enclose your table with a form tag. You have not provided the name of your controller(s), so I will use placeholders:
@using (Html.BeginForm("Delete", "NameOfControllerWithDeleteMethod"))
{
    //Put your table here
}

You will also need a field to hold the identifier of what you intend to delete. In this case, the file name itself:
@using (Html.BeginForm("Delete", "NameOfControllerWithDeleteMethod"))
{
    <input type="hidden" id="fileName" name="fileName" />
    //Put your table here
}

You will then need to populate this field with the name of the file you intend to delete. You can do so on the Click event of the Delete button. Replace your action link with an input of type submit and use JS to set it. Inside your loop. Notice the interpolation of JS strings and Razor code:
@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>
}

Lastly, on your controller’s Delete method you want to redirect back to your original Index method on both cases, whether you experienced an error or not. You can use the temporary data collection to pass back a message that only gets shown once:
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");
}

Collect this data in your view and show it somewhere:
@{ var userMessage = TempData["UserMessage"] as string; }
@if(!string.IsNullOrWhiteSpace(userMessage))
{
    <div class="some-message-style">@userMessage</div>
}


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x