WebApi ActionName удалить маршрут не работает - PullRequest
1 голос
/ 10 февраля 2020

мой проект содержит несколько контроллеров WebApi, и каждый из них обычно выполняет три действия: get (guid), post (data) и delete (guid),
Маршрут по умолчанию описан в WebApiconfig для этого требования. (имя: ControllerAndId)

Теперь мне нужно реализовать контроллер, который должен обрабатывать различные действия после публикации. Для этого требования я попытался сопоставить другой маршрут с ActionNames. (имя: ControllerAndActionAndId)

Поскольку я сопоставил маршрут ControllerAndActionAndId, невозможно вызвать маршрут удаления «обычного» контроллера (пример: Contactscontroller).
Все маршруты работают, кроме маршрутов удаления.

StatusCode: 404, ReasonPhrase: 'Not Found'

Существует пример обычно ApiController:

    public class ContactsController : ApiController
{
    public IEnumerable<Contact> Get()
    {
        return GetContacts();
    }

    public HttpResponseMessage Post(Contact contact)
    {            
        SaveContact(contact);

        return Request.CreateResponse<Guid>(_code, contact.Id);
    }

    public void Delete(Guid id)
    {
        DeleteContact(id);
    }
}

Контроллер с ActionName-Route:

    public class AttachmentsController : ApiController
{
    [HttpGet]
    public Attachment Get(Guid attachmentId)
    {
        return GetAttachment(attachmentId);
    }

    [HttpPost]
    [ActionName("save")]
    public HttpResponseMessage Save(AttachmentSaveData saveData)
    {
        SaveAttachment(saveData);
    }

    [HttpPost]
    [ActionName("remove")]
    public HttpResponseMessage Remove(AttachmentDeleteData deleteData)
    {
       DeleteAttachment(deleteData);            
    }
}

WebApiConfig:

            // Web API routes
        config.MapHttpAttributeRoutes();

        // Controller with ID
        // To handle routes like `/api/VTRouting/route/1`
        config.Routes.MapHttpRoute(
            name: "ControllerAndActionAndId",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new
            {
                id = RouteParameter.Optional,
                action = RouteParameter.Optional
            }
        );

        // Controller with ID
        // To handle routes like `/api/VTRouting/1`
        config.Routes.MapHttpRoute(
            name: "ControllerAndId",
            routeTemplate: "api/{controller}/{id}",
            defaults: new
            {
                id = RouteParameter.Optional
            }
        );

Функция удаления ClientAction:

        private void Delete(string uri, int id)
    {
        using (HttpClient _client = new HttpClient())
        {
            _client.BaseAddress = BaseAddress;
            string _url = string.Format("{0}/{1}", uri, id);
            var _response = _client.DeleteAsync(_url).Result;

            if (!_response.IsSuccessStatusCode)
            {
                throw new Exception();
            }
        }
    }

В настоящее время я понятия не имею, как решить эту проблему.

Ответы [ 2 ]

2 голосов
/ 10 февраля 2020

Если вы используете Web API, вам нужно добавить глагол HTTP к действию.

Например, ваш код должен быть таким, как показано ниже:

public class ContactsController : ApiController
{ 
    [HttpGet]
    public IEnumerable<Contact> Get()
    {
        return GetContacts();
    }

    [HttpPost]
    public HttpResponseMessage Post(Contact contact)
    {            
        SaveContact(contact);

        return Request.CreateResponse<Guid>(_code, contact.Id);
    }

    [HttpDelete]
    public void Delete(Guid id)
    {
        DeleteContact(id);
    }
}

Обратите внимание на действие Удалить .

  1. Если вы используете глагол HttpDelete для действия, вы должны отправить запрос на удаление от вашего клиента httpClient.DeleteAsync(...).
  2. Если вы используете глагол HttpPost для действия, вы должны отправить отправить запрос от вашего клиента httpClient.PostAsync(...).

AttachmentsController похож на ContactsController.

0 голосов
/ 10 февраля 2020

Многое сфокусировалось на действиях и маршрутах контроллера. Но решение было легко найти на стороне клиента:

        private void Delete<T>(string uri, T value)
    {
        using (HttpClient _client = new HttpClient())
        {
            _client.BaseAddress = BaseAddress;
            _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            string _url = string.Format("{0}/{1}", uri, value);
            var _response = _client.DeleteAsync(_url).Result;
        }
    }

Для этого решения требуется только один маршрут в WebApiConfig:

            config.Routes.MapHttpRoute(
            name: "ControllerAndId",
            routeTemplate: "api/{controller}/{id}",
            defaults: new
            {
                id = RouteParameter.Optional
            }
        );

Так легко ... большое спасибо!

...