web-dev-qa-db-fra.com

POST JSON avec contrôleur API MVC 4

J'ai ce code:

   $.ajax({


        type: "POST",
        url: "/api/slide",
        cache: false,
        contentType: "application/json; charset=utf-8",
        data: '{"Title":"fghfdhgfdgfd"}',
        dataType: "json",

Un c'est mon contrôleur:

public class SlideController : ApiController
{

    // POST /api/Slide
    public void Post(string Title)
    {
    }

Lorsque j'exécute le code et appelle le/api/Slide, le [Titre] ne contient aucune donnée et est null.

Comment puis-je publier du JSON sur le contrôleur de l'API?

POST http://127.0.0.2:81/api/slide HTTP/1.1
Host: 127.0.0.2:81
Connection: keep-alive
Content-Length: 18
Origin: http://127.0.0.2:81
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1
Content-Type: application/json; charset=UTF-8
Accept: application/json, text/javascript, */*; q=0.01
Referer: http://127.0.0.2:81/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

Title=fghfdhgfdgfd
17
user1615362

Définir un modèle de vue:

public class SlideViewModel
{
    public string Title { get; set; }
}

alors votre action de contrôleur prend ce modèle de vue en argument:

public class SlideController : ApiController
{
    // POST /api/Slide
    public void Post(SlideViewModel model)
    {
        ...
    }
}

enfin invoquer l'action:

$.ajax({
    type: 'POST',
    url: '/api/slide',
    cache: false,
    contentType: 'application/json; charset=utf-8',
    data: JSON.stringify({ title: "fghfdhgfdgfd" }),
    success: function() {
        ...    
    }
});

La raison en est que des types simples tels que des chaînes sont liés à l'URI. Je vous invite également à lire le article suivant à propos de la liaison de modèle dans l'API Web.

21
Darin Dimitrov

Assurez-vous que l'objet que vous essayez de convertir a un constructeur par défaut (vide). 

Règle de base: si vous souhaitez désérialiser un objet, vous devez le simplifier pour que les objets soient créés. Ces directives peuvent aider:

  • Toutes les propriétés à transmettre doivent être publiques  

  • l'objet doit pouvoir être construit sans aucun paramètre .

Cette chaîne/objet JSON par exemple:

{ Name: "John Doe", Phone: "123-456-7890", Pets: [ "dog", "cat", "snake" ] }

peut être converti en un objet de la classe suivante:

 public class Person {

     public string Name { get; set; }
     public string Phone { get; set; }
     public string[] Pets { get; set; }

  }

ou celui-ci:

public class Person {

   public string Name { get; set; }
   public string Phone { get; set; }
   public string[] Pets { get; set; }
   public Person() {}
   public Person(string name, string phone) {
      Name = name;
      Phone = phone;
   }

}

ou celui-ci:

public class Person {

    public string Name { get; set; }
    public string Phone { get; set; }
    public string[] Pets { get; set; }
    public Person() {}


 }

mais pas celui-ci

public class Person {

    public string Name { get; set; }
    public string Phone { get; set; }
    public string[] Pets { get; set; }
    public Person(string name, string phone) {
      Name = name;
      Phone = phone;
    }

}

Maintenant, laissez ASP.NET MVC 4 faire le reste

public class PersonController : ApiController
{
        // .. other actions 
        public HttpResponseMessage PostPerson(Person person)
        {
            if ( null != person)
                // CELEBRATE by doing something with your object
            else 
                // BE SAD and throw and exception or pass an error message

        }
        // .. other actions 
}

Si votre classe ne peut pas avoir de constructeur par défaut ou si vous n'avez pas accès au code source de la classe, vous pouvez créer une classe d'adaptateur qui

  • a un constructeur par défaut
  • expose les propriétés qui doivent être publiques

En utilisant la classe Person ci-dessus sans constructeur par défaut, un adaptateur pourrait ressembler à 

public class PersonAdapter {

    public Person personAdaptee;

    public string Name {
        get { return personAdaptee.Name; }
        set { personAdaptee.Name = value }
    }

    public string Phone {
        get { return personModel.Phone; }
        set { personModel.Phone = value; }
    }

    public string[] Pets {
        get { return personAdaptee.Pets; }
        set {personAdaptee.Pets = value }
    }

    public PersonAdapter() {

        personAdaptee = new Person("", "", null);

    }

}

Maintenant, laissez ASP.NET MVC 4 faire le reste

public class PersonController : ApiController
{
        // .. other actions 
        public HttpResponseMessage PostPerson(PersonAdapter person)
        {
            if ( null != person)
                // CELEBRATE by doing something with your object
            else 
                // BE SAD and throw and exception or pass an error message

        }
        // .. other actions 
}
10
Isioma Nnodum

Essaye ça:

$.ajax({
    type: "POST",
    url: "/api/slide",
    data: { Title: "fghfdhgfdgfd" }
});

Ce sont les guillemets autour de l'attribut data qui sont à l'origine de ceci:

i.e >> data: {Title: "fghfdhgfdgfd"} 
not >> data: ' {Title: "fghfdhgfdgfd"} '

METTRE À JOUR:
De plus, votre contrôleur semble un peu étrange, même s’il est difficile de le savoir sans voir votre routage, etc.

Je m'attendrais à voir quelque chose de plus semblable à ceci:

public class SlideController : ApiController
{
    public HttpResponseMessage PostSlide(string Title)
    {
        // Do your insert slide stuff here....

        string uri = Url.Link("DefaultApi", new { id = item.Id });
        response.Headers.Location = new Uri(uri);
        return response;
    }
}

Clairement, vous devrez également mettre à jour l'URL dans votre jQuery.

Jetez un coup d'oeil ici:

http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api

Une autre mise à jour:

Il serait habituel de créer un objet CLR correspondant à votre Json et d’utiliser le classeur de modèle MVC pour se lier directement à cet objet. Si vous ne voulez pas faire cela, vous pouvez vous lier à un objet et le désérialiser dans un dictionnaire:

// POST api/values
public void Post(object json)
{
    Dictionary<string, string> values = JsonConvert.DeserializeObject<Dictionary<string, string>>(json.ToString());
    var x = values["Title"];
}
2
Steve Lydford

Transforme le paramètre d'action en FromBody i.e:

public class SlideController : ApiController
{

    // POST /api/Slide
    public void Post([FromBody]string Title)
    {
    }
}
1
Bilal Saeed
$.ajax({
    type: 'POST',
    url: '/api/slide',
    cache: false,
    contentType: 'application/json; charset=utf-8',
    data: JSON.stringify({ title: "fghfdhgfdgfd" }),
    success: function() {
        ...    
    }
});

Contrôleur est 

public class SlideController : ApiController
{

    // POST /api/Slide
    public void Post(string Title)
    {
    }

Votre URL n'est pas valide, l'URL doit adresser l'action Post in Slide controller

éditez votre url en url: "~/ControllerName/ActionName" dans ce contexte doit être Url:"~/Slide/Post"

0
Ghebrehiywet