0

I'm working on my first MVC Core 2.1 app and encountered problem (i guess with the routing). When calling a POST method shown below:

    [HttpPost]
    public RedirectToActionResult Remove(int id)
    {
        Product p = _repository.Products.Where(x => x.Id == id).FirstOrDefault();
        _repository.Products.Remove(p);
        _repository.SaveChanges();
        return RedirectToAction("Index");
    }

i get the error 404 page not found. Below tag located in a partial view which sends the request:

<a method="POST" asp-controller="Product" asp-action="Remove" asp-route-id="@Model.Id" class="btn btn-danger">Delete</a>

it generates "https://localhost:44398/Product/Remove/3" (on product with id 3) which seems to be matching

I'm using default routing

app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });

also, if i change this same method from POST to get (getting rid of the database code) i'm able to access it

    [HttpGet]
    public RedirectToActionResult Remove(int id)
    {

        return RedirectToAction("Index");
    }

I bet I've made some stupid mistake, but I'm stuck with it and can't find the answer. Any help will be appreciated!

2
  • 1
    look at the answers here: stackoverflow.com/questions/8169027/… Commented Nov 11, 2019 at 22:33
  • You cannot send POST requests using anchor element. Consider using form with proper method Commented Nov 12, 2019 at 8:39

5 Answers 5

1

First of all, why would you need Post if you are passing just an Id through query string?

Also, if i recall correctly Post you need to setup Content-Type Headers when calling post verb.

Sign up to request clarification or add additional context in comments.

2 Comments

I used POST because in this action I'm going to mess with my database. I'm not sure about the second part of your answer, the other POST method that is creating products from form and placing them into the DB is working fine.
@Golemiash to be honest, I think using GET to do the deletion is fine if you are doing through the UI the way you pasted it. Because the framework will do some security for you.
0

HTTP POST requests supply additional data from the client (browser) to the server in the message body. In contrast, GET requests include all required data in the URL. Forms in HTML can use either method by specifying method="POST" or method="GET" (default) in the element. The method specified determines how form data is submitted to the server. When the method is GET, all form data is encoded into the URL, appended to the action URL as query string parameters. With POST, form data appears within the message body of the HTTP request.

Refer to the following links for more details on the differences between Get and Post : https://stackoverflow.com/a/3477374/10201850

https://www.diffen.com/difference/GET-vs-POST-HTTP-Requests

Comments

0

You can try like below-

<form method="post">
        <input name="id" type="text" value="2" />
        <button type="submit" asp-controller="Product" asp-action="Remove">Click Me </button>
</form>

This is one way to pass the data to the action using form POST. Model binding automatically binds the data from the form to the action parameters. The name of the input tag is used for binding the data dynamically.

I hope this helps.

Comments

0

One thing: If you are using persisting data and want to delete a object that his primary key is in another table as FK you must need to make a logic erase, thats why you are not able to delete, if not your problem: I´m newbie also and I´m working on .NET Core 3 so my routes looks like:

 app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: null,
                pattern: "{category}/Page{productPage:int}",
                defaults: new { controller = "Product", action = "List" }
            );
            endpoints.MapControllerRoute(
                name: null,
                pattern: "Page{productPage:int}",
                defaults: new
                {
                    controller = "Product",
                    action = "List",
                    productPage = 1
                }
                 ...
            );
// And my default:
            endpoints.MapControllerRoute("default", "{controller=Product}/{action=List}/{id?}");

This is a form for one of my projects:

<form asp-action="Delete" method="post">
                    <a asp-action="Edit" class="btn btn-sm btn-warning"
                       asp-route-productId="@item.ProductID">
                        Edit
                    </a>
                    <input type="hidden" name="ProductID" value="@item.ProductID" />
                    <button type="submit" class="btn btn-danger btn-sm">
                        Delete
                    </button>
                </form>

There´s a difference here: Mine: asp-route-productId="@item.ProductID" Yours: asp-route-id="@Model.Id" How did you call it?

This is my Edit method:

 [HttpPost]
        public IActionResult Delete(int productId)
        {
            Product deletedProduct = repository.DeleteProduct(productId);
            if(deletedProduct != null)
            {
                TempData["message"] = $"{deletedProduct.Name} ha sido borrado";
            }
            return RedirectToAction("Index");
        }
    }

And the last call:

public Product DeleteProduct(int productID)
        {
            Product dbEntry = context.Products
                .FirstOrDefault(p => p.ProductID == productID);
            if(dbEntry != null)
            {
                context.Products.Remove(dbEntry);
                context.SaveChanges();
            }
            return dbEntry;
        }

You can try to: Change to IActionResult instead RedirectToActionResult .

Comments

0

if is working before, resend web config file to server, it will reset application. I guess in publish web config file should be latest file.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.