Kontroler WebAPI nie jest dostępny po poleceniu DELETE

Mam problem z uruchomieniem metody DELETE na moim kontrolerze podczas składania żądania ASP.NET Web API. Zwraca 404, ale nie wiem dlaczego. Żądania GET & POST działają zgodnie z oczekiwaniami, zwracając zarówno listę elementów, jak i pojedynczy element po podaniu identyfikatora, ale gdy wywołuję API za pomocą żądania DELETE, dostaję błąd 404.

Scenariusz:

1. ASP.NET aplikacja Web Forms ...

Nie jest aplikacją MVC, chociaż zainstalowałem Pakiet MVC4 w celu wykorzystania funkcji Web API.

2. Definicja tabeli tras w trybie globalnym.asax

            RouteTable.Routes.MapHttpRoute(

                    "Default", 
                    "api/{controller}/{id}", 
                    new { id = RouteParameter.Optional } 
            );

3. Definicja kontrolera

    public HttpResponseMessage<Customer> Post(Customer customer)
    {
        CustomerDb.Customers.AddObject(customer);
        CustomerDb.SaveChanges();
        var response = new HttpResponseMessage<Customer>(customer, HttpStatusCode.Created);
        response.Headers.Location = new Uri(Request.RequestUri, "/api/Customer/"+customer.id.ToString());
        return response;
    }

    public CustomerDTO Get(int id)
    {
        CustomerDTO custDTO = null;
        Customer cust = CustomerDb.Customers.Where(c => c.id == id).SingleOrDefault();
        if (cust == null)
            throw new HttpResponseException(HttpStatusCode.BadRequest);
        else
            custDTO = new CustomerDTO(cust);
        return custDTO;
    }

    public IEnumerable<CustomerDTO> Get()
    {
        IQueryable<Customer> custs = CustomerDb.Customers.AsQueryable();

        List<CustomerDTO> dto = new List<CustomerDTO>();
        foreach (Customer cust in custs)
        {
            dto.Add(new CustomerDTO(cust));
        }

        return dto;
    }

    public Customer Delete(int id)
    {
        Customer cust = CustomerDb.Customers.Where(c => c.id == id).SingleOrDefault();
        if (cust == null)
            throw new HttpResponseException(HttpStatusCode.BadRequest);

        CustomerDb.Customers.DeleteObject(cust);
        CustomerDb.SaveChanges();
        return (cust);
    }

Mam kilka metod rzucających błąd BadRequest zamiast 404, gdy klient nie może zostać znaleziony, więc nie mam tych odpowiedzi mylonych z prawdziwym problemem. Oczywiście w prawdziwej implementacji żaden klient nie zwróci błędu 404.

4. Wywołanie Ajax przez JQuery w celu usunięcia elementu.

function deleteCustomer(id) {

        var apiUrl = "/api/customer/{0}";
        apiUrl = apiUrl.replace("{0}", id);

        $.ajax({
            url: apiUrl,
            type: 'DELETE',
            cache: false,
            statusCode: {
                200: function (data) {
                }, // Successful DELETE
                404: function (data) {
                    alert(apiUrl + " ... Not Found");
                }, // 404 Not Found
                400: function (data) {
                    alert("Bad Request O");
                } // 400 Bad Request
            } // statusCode
        }); // ajax call
    };

Więc oczekuję że mapa trasy singel powinna uwzględniać wszystkie scenariusze ...

  1. GET api / customer -- zwraca wszystkich klientów
  2. GET api / customer / 5 -- zwraca klienta, którego ID = 5
  3. POST api / klient -- tworzy nowy rekord klienta
  4. DELETE api/customer / 5 -- usuwa klienta, którego ID = 5

1,2 & 3 działają bez problemu, tylko DELET nie działa. Próbowałem wielu iteracji i różnych poprawek, bez skutku. I nadal czuję jednak, że przeoczyłem coś małego. Wydaje mi się, że problem musi być wokół mapowania, ale nie widzę powodu, dla którego ta trasa nie poradziłaby sobie z żądaniem usunięcia.

Każda pomoc byłaby bardzo mile widziana. Dziękuję!

Gary

Author: Gary O. Stenstrom, 2012-03-14

3 answers

Czy masz to zdefiniowane w swojej sieci.config?

   <system.webServer>
          <modules runAllManagedModulesForAllRequests="true">
          </modules>
    </system.webServer>
 27
Author: Dave Bettin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-13 22:09:12

Spróbuj zwrócić HttpResponseMessage w metodzie Delete

public HttpResponseMessage Delete( string id )
{
  Customer cust = CustomerDb.Customers.Where(c => c.id == id).SingleOrDefault();
  if (cust == null)
    return new HttpResponseException( HttpStatusCode.NotFound ); // using NotFound rather than bad request

  CustomerDb.Customers.DeleteObject(cust);
  CustomerDb.SaveChanges();
  return new HttpResponseMessage( HttpStatusCode.NoContent );
}
 -1
Author: TheRightChoyce,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-17 17:28:04

Musisz zaimplementować metodę Delete w kontrolerze:

// DELETE /api/values/5
public void Delete(int id) {}
 -3
Author: adriano001,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-13 21:55:02