2016-12-23 2 views
4

У меня есть действие контроллера, которое берет документ JSON как тело запроса POST. Я хотел бы, чтобы автоматически создать JObject от того, с помощью модели связывания, например:В ASP.NET MVC, могу ли я автоматически моделировать привязку к объекту JObject из тела POST?

[HttpPost] 
public ActionResult Index([FromBody] JObject data) 
{ 
    // "data" is now a populated JObject object 
} 

Но я получаю ошибки о не создавая абстрактный класс. Я пытался что-то продлить с JObject, но это тоже не получится.

Я знаю, что могу просто прочитать тело запроса и называть его JObject.Parse (я делаю это, поэтому он действительно работает), но моя идея сверху кажется гораздо более элегантной.

Возможно ли это?

Edit: Фактическая ошибка:

System.MissingMethodException: Cannot create an abstract class. 
[MissingMethodException: Cannot create an abstract class.] 
System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) 
[Stack trace continues...] 

Запрос никогда не попадает в действие контроллера.

На основе моих исследований JObject не абстрактно, а просто, чтобы быть уверенным, я сделал это:

public class Entry : JObject 

Тогда

public ActionResult Index([FromBody] Entry data) 

Не работает. Такая же ошибка.

+0

Является ли JSON вашего документа типа JObject? – CodingYoshi

+0

'JObject' - всего лишь общий объект для размещения JSON любого типа. Подобный «XmlDocument» хранит XML любого типа. Это из библиотеки 'JSON.Net'. – Deane

+0

Является ли 'FromBody' чем-то, что вы создали? – CodingYoshi

ответ

2

Возможно, были две проблемы. Я изменил две вещи, и теперь это работает, но я не уверен на 100%, что это исправлено.

Вот как то, что я изменилась -

Во-первых, я унаследовал от ApiController вместо просто Controller. Я не уверен, что это связано с этим.

Во-вторых, один из других ответов указал, что мне нужен правильный заголовок Content-Typeapplication/json. Ну, это не так.Заголовок Content-Type был настроен на некоторое дикое значение, специфичное для программного обеспечения, с которым мы интегрируемся.

Так, в Application_Start, я прибавил:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("[crazy ass content-type header value]")); 

А потом он работал.

Я подозреваю, что это было второе, что зафиксировало это. Так как заголовок не сообщил модельному связующему, это был входящий JSON, связующее пыталось создать объект JObject с нуля и присвоить свойства через отражение, которое столкнулось с проблемами, когда JToken является абстрактным. Когда-то он знал, что это имеет дело с JSON, он знал, что просто позвонил JObject.Parse.

0

Вы также должны поместить структуру JSON в свой вопрос. Полный запрос будет лучше. До тех пор, попробуйте следующее:

заменить [FromBody] JObject data с [FromBody] dynamic data или [FromBody] object data

и посмотреть, если он попадает в точку останова поставить на первой линии действия.

Если это так, посмотрите, что на самом деле ваша динамика (тип).

Если это не так, может быть, запрос POST не Content-Type: application/json

+0

Последнее предложение в этом ответе помогло мне это решить. См. Мой ответ. – Deane

+0

Рад это услышать :) – Alexei

0

Вопрос заключается в том, что в какой-то момент, когда десериализации ввести JObject, он вызывает, чтобы создать `JToken» и что, где исключение , Вот точное исключение:

Невозможно создать абстрактный класс. Тип объекта Newtonsoft.Json.Linq.JToken