2016-12-23 1 views
4

J'ai une action de contrôleur qui prend un document JSON comme le corps d'une requête POST. J'aimerais créer automatiquement un JObject de cela, par modèle de liaison, comme ceci:Dans ASP.NET MVC, puis-je modéliser automatiquement un lien vers un JObject à partir du corps POST?

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

Mais je reçois des erreurs de ne pas créer une classe abstraite. J'ai essayé d'étendre quelque chose de JObject, mais ce ne serait pas non plus le cas.

Je sais que je peux juste lire le corps de la demande et appeler JObject.Parse dessus (je fais ceci, ainsi cela fonctionne), mais mon idée d'en haut semble tellement plus élégante.

Est-ce possible?

Edit: L'erreur réelle est:

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...] 

La demande ne fait jamais dans l'action du contrôleur.

D'après mes recherches JObject n'est pas abstraite, mais juste pour être sûr, je l'ai fait:

public class Entry : JObject 

Puis

public ActionResult Index([FromBody] Entry data) 

ne fonctionne pas. Même erreur

+0

est votre JSON d'un document de type jobject? – CodingYoshi

+0

'JObject' est juste un objet générique pour contenir JSON de n'importe quel type. Un peu comme 'XmlDocument' contient du XML de n'importe quel type. Ceci provient de la bibliothèque 'JSON.Net'. – Deane

+0

Est-ce que 'FromBody' est quelque chose que vous avez créé? – CodingYoshi

Répondre

2

Il peut y avoir eu deux problèmes. J'ai changé deux choses, et ça marche maintenant, mais je ne suis pas sûre à 100% de savoir laquelle a été corrigée.

Voici les deux choses que je changé -

D'abord, je hérité de ApiController au lieu de simplement Controller. Je ne suis pas sûr si cela a quelque chose à voir avec ça. Deuxièmement, l'une des autres réponses a souligné que je devais avoir l'Content-Type en-tête correct de application/json. Eh bien, ce n'était pas.L'en-tête Content-Type correspond à une valeur spécifique au logiciel que nous intégrons.

Ainsi, dans Application_Start, j'ajouté ceci:

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

Et cela a fonctionné. Je soupçonne que c'était la deuxième chose qui l'a corrigé. Puisque l'en-tête ne disait pas au classeur modèle qu'il était JSON entrant, le classeur essayait de créer un objet JObject à partir de rien et d'assigner des propriétés par réflexion qui rencontraient des problèmes avec JToken étant abstrait. Une fois qu'il a su qu'il traitait avec JSON, il a su appeler simplement JObject.Parse à la place.

0

Vous devez également mettre la structure du JSON dans votre question. La demande complète serait mieux. Jusque-là, procédez comme suit:

[FromBody] JObject data avec [FromBody] dynamic data remplacer ou [FromBody] object data

et voir si elle touche un point d'arrêt mis sur la première ligne de l'action. Si c'est le cas, voyez ce qu'est réellement votre dynamique (type).

Si elle ne le fait pas, peut-être la demande POST ne pas Content-Type: application/json

+0

La dernière phrase de cette réponse m'a aidé à le résoudre. Vois ma réponse. – Deane

+0

Content de l'entendre :) – Alexei

0

Le problème est que, à un moment où désérialisation taper JObject, il appelle à créer un `JToken » et qui est où l'exception est levée . Voici l'exception exacte:

Impossible de créer une classe abstraite. Type d'objet Newtonsoft.Json.Linq.JToken