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!

Golemiash
  • 3
  • 2
  • 1
    look at the answers here: https://stackoverflow.com/questions/8169027/how-can-i-submit-a-post-form-using-the-a-href-tag – roozbeh S Nov 11 '19 at 22:33
  • You cannot send `POST` requests using `anchor` element. Consider using `form` with proper method – Alexander Nov 12 '19 at 08:39

5 Answers5

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.

  • 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 Nov 11 '19 at 21:51
  • @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. – Robison Karls Custódio Nov 13 '19 at 13:56
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.

kode_anil
  • 66
  • 1
  • 6
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

Xueli Chen
  • 9,094
  • 1
  • 14
  • 29
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 .

Qiqke
  • 481
  • 3
  • 14
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.

zamoldar
  • 460
  • 8
  • 12