2017-02-01 7 views
0

Прежде всего, позвольте мне сказать, что есть много подобных вопросов, которые уже были отправлены здесь, но я пробовал все решения и не испытывал радости ,Передача данных из jQuery Ajax вызов MVC ApiController Действие теряет данные

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

public void Post([FromBody] Employee employee) 

Я попытался с или без [FromBody].

Мой класс Employee имеет 5 членов базовых типов, INT, строка, строка, строка, двойная

Я звоню Действие от отдельного домена (как на моем локальном хосте с помощью Корс), используя 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", 

в сочетании с различными способами «stringify» мой персонал объекта:

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

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

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

public void Delete([FromBody] int employeeId) 

Опять же, я не могу передать employeeId в «желаемом» способе.

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

 data: { 
      employeeId: 100 
     }, 

Для работы!?!

Я могу заставить метод Delete работать, я меняю его на [FromUri] и укажу «? EmployeeId = 100» в вызывающем Url.

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

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

Спасибо.

Дополнительная информация о вызове «Удалить».

Если я использую Почтальон, удалить требование для проверки подлинности, указать Content-Type "приложения/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." 
} 

ответ

0

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

data: JSON.stringify({ employee : employee }) 
+0

Я пробовал это. Опять же со всеми комбинациями dataType/contentType. Вызывается метод, но все свойства объекта Employee по-прежнему имеют значения по умолчанию null, 0 в действии ApiController. –

+1

попробуйте добавить 'CONTENTTYPE: 'приложение/JSON', DATATYPE: "JSON"' к вашим '$ .ajax' установкам – JohanP

+0

Тем не менее объект работника на сервере имеет значение по умолчанию: вара работника = { Id: 100, FirstName: "Fred", LastName: "Блоги" Пол: Мужской, Зарплата: 100000 }; $ .ajax ({ URL: "HTTP: // ..., типа: "POST", заголовки: { "Авторизация": "Знаменосец" + sessionStorage.getItem (" маркер доступа ") }, contentType: "application/json", dataType: "json", данные: JSON.stringify ({employee: employee}), –

1

Я не думаю, что «DELETE» проходит тело, как «POST» так [FromBody] не будет работать, если вы звоните Аякса вызов типа: «Удалить».

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

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

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

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

Это позволяет звонить с АЯКС данными:

data: { 
     employee: employee 
    }, 
+0

** Это сработало **. Как вы, кажется, указали, что это немного грязно Я бы подумал, что один из параметров stringify() на стороне клиента будет форматировать данные таким образом, чтобы я мог напрямую использовать объект Employee. –

+0

Яркий комментарий об Delete() Я буду исследовать позже. Я предполагаю, что Post/Путь должен работать одинаково. –

0

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

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

    employee = JSON.stringify(employee); 

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

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

Также удалось получить DELETE, работающий в теле сообщения точно так же.