web-dev-qa-db-fra.com

Impossible de publier des données de chaîne simples sur l'API Web à partir d'AngularJS

J'essaie d'obtenir une chaîne json de mon angular vers une API Web. J'ai regardé partout sur Internet au cours des 6 dernières heures en essayant et en échouant lamentablement pour comprendre ce que je fais mal.

J'ai vérifié la console réseau et je peux voir le json comme des données de formulaire, mais mon API WEB pour une raison quelconque ne l'obtient pas. J'ai regardé plusieurs autres messages mais aucun ne semble aider avec mon problème particulier. Toute direction serait formidable. J'ai déjà essayé d'utiliser le correctif "transform", mais cela n'a pas aidé.

POINTS D'ENTRÉE SUR L'API WEB

[HttpPost]
[Route("api/SkeltaInterfaceController/SaveWorkflow")]
public bool SaveWorkflow([FromBody] string json)
{
    ...
}

APPEL ANGULAIRE

$scope.SaveWorkFlow = function () {
    $http({
        headers: {'Content-Type': 'application/x-www-form-urlencoded'},
        method: "POST",
        url: webAPI,
        data: {'DATA' : 'TEST DATA'
        }
    })
}

EDIT: I a changé l'appel angular à cet

$scope.SaveWorkFlow = function () {
    $http({
        headers: {'Content-Type': 'application/x-www-form-urlencoded'},
        method: "POST",
        url: webAPI,
        data: {'DATA' : 'TEST DATA'}
    })
}

L'API Web ressemble à ceci

[HttpPost]
[Route("api/SkeltaInterfaceController/SaveWorkflow")]
public bool SaveWorkflow([FromBody] TestModel json)
{
    ...
}

Et le modèle

public class TestModel
{
    public string DATA { get; set; }
}

Je reçois toujours une valeur nulle pour DATA, quelque chose que j'ai mal configuré?

10
Willy

Je pense que votre problème se résume à la méthode du contrôleur WebApi s'attendant à recevoir une chaîne, mais vous lui passez un objet. Est-ce au moins de frapper la méthode mais de recevoir null?

Cela dépend de ce que vous essayez d'envoyer à la méthode du contrôleur WebApi, mais si vous voulez envoyer un objet, vous devez créer un modèle qui représente cet objet dans votre projet WebApi et demander à la méthode de prendre un objet comme paramètre.

Par exemple, comme vous l'avez en ce moment, vous feriez quelque chose comme:

public class SaveModel 
{
    public string DATA {get; set;}
}


[HttpPost]
[Route("api/SkeltaInterfaceController/SaveWorkflow")]
public bool SaveWorkflow([FromBody] SaveModel model)
{ ...
7
mattherman

Bien que vous ayez une solution, il existe plusieurs façons de POST simple string données (pas un objet) à un service Web API.

Disons que vous avez une POST comme celle-ci (dans Test ApiController)

public void Post([FromBody]string value)
{
    //do something with value
}

Depuis AngularJS vous pouvez poster sur cette méthode comme

(1) données sous la forme JSON (par défaut)

$scope.Test = function () {
    $http({
        method: "POST",
        url: "/api/Test",
        data: JSON.stringify("test")
    });
};

Cela utilisera Content-Type: application/json Par défaut. Et le serveur traitera les données comme JSON. Si vous regardez la demande, vous verrez que le corps de la demande est une simple chaîne, comme

"test"

Pour les objets complexes, vous les verriez au format JSON.

(2) données comme application/x-www-form-urlencoded (Comme dans votre exemple)

$scope.Test = function () {
    $http({
        headers: {'Content-Type': 'application/x-www-form-urlencoded'},
        method: "POST",
        url: "/api/Test",
        data: $.param({ "": "test" }),
    });
};

Ici, nous spécifions explicitement le type de contenu à application/x-www-form-urlencoded, Nous devons donc envoyer des données dans ce format (un peu comme la chaîne de requête URL). Et, ici, la clé vide dans les données est juste pour satisfaire l'étrange modèle de Web API Les données résultantes seront encodées comme

=test

ce que nous avons fait avec $.param({ "": "test" }). Une des raisons pour cela, FromBody est principalement utilisée pour envoyer object, et non de simples valeurs primitives.

Donc, la base problème avec votre code était, vous aviez spécifié Type de contenu: application/x-www-form-urlencoded et vous envoyiez les données en tant que JSON!

33
Arghya C