Передача данных из вызова jQuery Ajax в MVC ApiController Action теряет данные

Во-первых, позвольте мне сказать, что на этот вопрос уже было выложено много похожих вопросов, но я попробовал все решения и не испытал радости.

У меня есть MVC ApiController Action, чья подпись:

    public void Post([FromBody] Employee employee)

Я пробовал с или без [FromBody].

Мой класс Employee имеет 5 членов базовых типов: int, string, string, string, double

Я вызываю Action из отдельного домена (оба на моем локальном хосте с использованием Cors), используя jQuery Ajax следующим образом:

    $.ajax({
        url: "http://localhost:55555/api/Employees",
        type: "POST",
        headers: {
            "Authorization": "Bearer " + sessionStorage.getItem("accessToken")
        },
        data: {
            Id: 100,
            FirstName: "Fred",
            LastName: "Blogs",
            Gender: "Male",
            Salary: 100000
        },
        // ...

Это работает абсолютно нормально. Там нет проблем с авторизацией. Объект Employee на контроллере заполняется этими данными. Но я хочу отправить данные более "структурированным" способом. Поэтому мои данные будут выглядеть примерно так:

        data: {
            employee: employee
        },

Я перепробовал все, что мог придумать, чтобы отформатировать сотрудника. Указаны все комбинации:

        contentType: "application/json; charset=utf-8",
        dataType: "json", 

В сочетании с различными способами "зачеркнуть" объект моего сотрудника:

    var employee = {
        Id: 100,
        FirstName: "Fred",
        LastName: "Blogs",
        Gender: "Male",
        Salary: 100000
    };

    employee = JSON.stringify({ "employee": employee });
    employee = JSON.stringify(employee);

В случае, если это связано (как более простой пример), у меня также есть этот метод на моем ApiController:

public void Delete([FromBody] int employeeId)

Опять же, я не могу передать идентификатор сотрудника "желаемым" способом.

Я даже не могу получить:

        data: {
            employeeId: 100
        },

Работать!?!

Я могу заставить метод Delete работать, я изменяю его на [FromUri] и указываю "? EmployeeId=100" в URL-адресе вызова.

Я надеялся, что смогу быть более последовательным при разных вызовах и всегда передавать "объект" в формате JSON.

У кого-нибудь есть идеи, которые могут помочь мне прогрессировать?

Благодарю.

Более подробная информация об удалении вызова.

Если я использую Почтальон, снимаю требование для Аутентификации, указываю Content-Type "application/json" в заголовке и employeeId=100 в теле, Почтальон возвращает:

{
  "Message": "The request is invalid.",
  "MessageDetail": "The parameters dictionary contains a null entry for parameter 'employeeId' of non-nullable type 'System.Int32' for method 'Void Delete(Int32)' in 'WebApi.Controllers.EmployeesController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter."
}

3 ответа

Я не думаю, что "DELETE" передает тело как "POST", поэтому [FromBody] не будет работать, если вы вызываете вызов ajax с типом: "Delete".

Что касается сотрудника после звонка, я видел аналогичные проблемы. Единственное, что я мог найти, - это создать класс-обертку, который обернет сотрудника.

public class EmployeeWrapper {
    public Employee employee {get; set;}
}

Тогда у вас EmployeeWrapper будет параметром для метода Post.

 public void Post([FromBody] EmployeeWrapper employeeWrapper)  {
      Employee employee = employeeWrapper.employee;
      ...

Это позволяет вам звонить с данными ajax:

data: {
        employee: employee
    },

Следующая комбинация наконец исправила мою проблему.

    var employee = {
        Id: 100,
        FirstName: "Fred",
        LastName: "Blogs",
        Gender: "Male",
        Salary: 100000
    };

    employee = JSON.stringify(employee);

    //...
    contentType: "application/json",
    data: employee,
    //...

Одна из причин, по которой я не пришел к этому раньше, заключалась в том, что я старался окружить данные: { ... } фигурными скобками. Это заставляло это терпеть неудачу.

Также удалось заставить DELETE работать в теле сообщения точно таким же образом.

+ Изменить data к этому:

data: JSON.stringify({ employee : employee })
Другие вопросы по тегам