O parâmetro Post é sempre nulo

197

Desde a atualização para RC para WebAPI, estou tendo um problema muito estranho ao chamar o POST na minha WebAPI. Eu até voltei à versão básica gerada no novo projeto. Assim:

public void Post(string value)
{
}

e ligando do Fiddler:

Header:
User-Agent: Fiddler
Host: localhost:60725
Content-Type: application/json
Content-Length: 29

Body:
{
    "value": "test"
}

Quando depuro, a string "value" nunca está sendo atribuída. É sempre sempre NULL. Alguém está tendo esse problema?

(Vi o problema pela primeira vez com um tipo mais complexo)

O problema não está vinculado apenas ao ASP.NET MVC 4, o mesmo problema ocorre para um projeto novo do ASP.NET MVC 3 após a instalação do RC

ianrathbone
fonte
Apenas para aumentar o problema - não é exclusivo do JSON, também acontece com o XML.
Ianrathbone
3
Estou discutindo isso há dois dias e, depois de ler todos os artigos que pude encontrar, ficou tão simples quanto formatar a string JSON corretamente no WebRequest: Os dados devem começar e terminar com aspas duplas e, se você use aspas simples em todos os seus dados json, tudo funciona bem.
Gineer

Respostas:

101

Como você possui apenas um parâmetro, tente decorá-lo com o [FromBody]atributo ou altere o método para aceitar um DTO com valor como uma propriedade, como sugeri aqui: Ligação de parâmetro do MVC4 RC WebApi

ATUALIZAÇÃO: o site oficial do ASP.NET foi atualizado hoje com uma excelente explicação: https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/sending-html-form-data-part- 1

Em poucas palavras, ao enviar um único tipo simples no corpo, envie apenas o valor prefixado com um sinal de igual (=), por exemplo, body:

=test

Jim Harte
fonte
9
I deu o [FromBody] um turbilhão, mas ele não tinha alterações
ianrathbone
11
Passe apenas o valor (ou seja, não como um objeto JSON) e ele deve funcionar, de acordo com blogs.msdn.com/b/jmstall/archive/2012/04/16/...
Jim Harte
8
O anexo =à frente nunca funcionou para mim, até eu seguir o conselho de Jim em seu comentário (não como um objeto JSON) e funcionou. Isso é fundamental! Eu realmente não gosto de como WebAPI exigente é.
gitsitgo
16
Isso é tão estúpido e irritante que eu não sei se vou votar ou não com a resposta que me ajudou a resolver meu problema ... Por que diabos isso tem que estar nesse formato? (Desculpe pela atitude, perdi muito tempo com isso e isso não faz sentido ... :(). Você realmente deve adicionar suporte ao formato que as pessoas esperam que ele aceite.
gdoron está apoiando Monica
6
Obrigado! Como na Terra devemos saber que precisamos remover o nome do parâmetro ao enviar apenas um parâmetro? Qual birdbrain teve essa ideia?
Jenny O'Reilly
104

Eu tenho coçado minha cabeça hoje.

Minha solução é mudar [FromBody]para umHttpRequestMessage , essencialmente movendo a pilha HTTP.

No meu caso, estou enviando dados através do fio que é zipado json que é então base64'd. Tudo isso em um aplicativo Android.

A assinatura original do meu endpoint da Web era assim (usando [FromBody]):

Meu endpoint original

Minha correção para esse problema foi voltar a usar a HttpRequestMessagepara a assinatura do meu endpoint.

insira a descrição da imagem aqui

Você pode obter acesso aos dados da postagem usando esta linha de código:

insira a descrição da imagem aqui

Isso funciona e permite o acesso aos dados brutos intocados da publicação. Você não precisa mexer com o violinista colocando um sinal = no início da sua string ou alterando o tipo de conteúdo.

Como um aparte, primeiro tentei seguir uma das respostas acima, que foi alterar o tipo de conteúdo para: "Tipo de conteúdo: application / x-www-form-urlencoded". Para dados brutos, esse é um mau conselho, porque retira + caracteres.

Portanto, uma sequência base64 que começa assim: "MQ0AAB + LCAAAAAA" termina assim "MQ0AAB LCAAAAAA"! Não é o que você quer.

Outro benefício do uso HttpRequestMessageé que você obtém acesso a todos os cabeçalhos http de dentro do seu endpoint.

Ocean Airdrop
fonte
6
Excelente solução ... Levei 9 horas para encontrar isso, resolvi meu problema depois que eu removi o valor da string [FromBody] e o substitui pelo HttpRequestMessage
Kev
1
Funciona como um encanto! mas não existe uma maneira de usar um tipo de parâmetro real de um determinado objeto? por exemplo, parâmetro do tipo Order para um método de API da Web?
Ron Nuni
7
Apenas uma nota lateral, você NÃO PRECISA da HttpRequestMessage requestassinatura do método, pois sempre a possui. No corpo do método, ele pode ser acessado no Requestobjeto. por exemploRequest.Content.ReadAsStringAsync().Result;
Morvael 29/03
Geralmente, esse problema ocorre porque o objeto JSON está incorreto. Eu descobri que isso é sempre porque o construtor tem um tipo inválido e o Json não sabe como convertê-lo 'Como um Guid para uma string. Portanto, adicione o conversor via configurações ou adicione um construtor em branco e não será necessário voltar ao código antigo como este.
Nick Turner
A maneira mais fácil é alternar o objeto para uma sequência e, em seguida, tentar convertê-lo e você verá o erro JSON. Verifique se você também é cabeçalhos.
Nick Turner
71

Acabei de ocorrer usando o Fiddler. O problema era que eu não havia especificadoContent-Type .

Tente incluir um cabeçalho Content-Typena sua solicitação POST.

Content-Type: application/x-www-form-urlencoded

Como alternativa, conforme os comentários abaixo, pode ser necessário incluir um cabeçalho JSON

Content-Type: application/json
Kirk Broadhurst
fonte
11
Eu tive um problema semelhante, exceto que eu precisava para definir o Content-Type: application / json
dvallejo
2
Conforme especificado no pós - Eu já tinha adicionado Content-Type: application / json
ianrathbone
2
application / x-www-form-urlencoded não funcionou para mim, tipo de conteúdo: application / json funcionou.
Liang3 /
1
Independentemente do tipo de conteúdo, se você tiver apenas um parâmetro, deverá enviar apenas o valor sem o nome do parâmetro no corpo da solicitação. Então id = 13 não funcionará. Você precisa enviar 13 sozinho. Veja a resposta de Jim.
Jenny O'Reilly
Eu tive que usar contentType: "application/x-www-form-urlencoded; charset=UTF-8", para obter um exemplo completo, veja Complete Cient and Server
RyBolt 24/08/16
57

Eu também encontrei esse problema e foi assim que resolvi meu problema

código webapi:

public void Post([FromBody] dynamic data)
{
    string value = data.value;
    /* do stuff */
}

Código do cliente:

$.post( "webapi/address", { value: "some value" } );
George
fonte
1
Isso funciona se o cliente estiver enviando JSON. Se estou enviando um valor simples, como a sequência some value, então dataé nulo.
Brianestey # 8/16
fácil, altere o código do cliente para enviar de volta um objeto js.
George
Maneira
Se você estiver enviando json, var json = JsonConvert.SerializeObject (data);
Dvallejo 7/03/19
41

Eu estava usando Postmane estava cometendo o mesmo erro .. passando o valueobjeto as json em vez de string

{
    "value": "test"
}

Claramente, o acima está errado quando o parâmetro api é do tipo string.

Então, basta passar a string entre aspas duplas no corpo da API:

"test"
JerryGoyal
fonte
2
Este foi o meu problema, e provavelmente a verdadeira solução para a questão. Uma cadeia de caracteres codificada em JSON tem aspas
Kyle W
1
Eu também encontrei esse problema no Postman. Acontece que eu escolhi erroneamente "form-data" em vez de "raw" para Body quando o Content-Type está definido como application / json. Você pode consultar as imagens das zzyykk123456 para as questões de aspnet Github: github.com/aspnet/Home/issues/2202
Chun Lin
Isso funcionou para mim. Usando o Swagger (swashbuckle), tenho que definir o Tipo de conteúdo: application / json e usar aspas duplas.
John Henckel
1
Exatamente o meu problema. Mas devo observar que, nos pedidos do Ajax, você deve fazer 'data: JSON.stringify ("YourString")' '
Amir Hossein Ahmadi
1
@AmirHosseinAhmadi Acabei de encontrar isso no ajax e vi que realmente usar JSON.stringifyestava fazendo com que eu [frombody]estivesse null. Depois de definir o campo de dados para um valor de sequência (que é uma sequência json), funcionou.
Nexaspx 4/03/19
19

Tente criar uma classe para servir como modelo de dados e, em seguida, envie um objeto JSON com propriedades correspondentes às propriedades da sua classe de modelo de dados. (Nota: testei isso e funciona com o mais novo MVC 4 RC 2012 que baixei hoje).

public HttpResponseMessage Post(ValueModel model)
{
    return Request.CreateResponse<string>(HttpStatusCode.OK, "Value Recieved: " + model.Value);
}

public class ValueModel
{
    public string Value { get; set; }
}

O objeto JSON abaixo é enviado no corpo HTTP-POST, o tipo de conteúdo é application / json

{ "value": "In MVC4 Beta you could map to simple types like string, but testing with RC 2012 I have only been able to map to DataModels and only JSON (application/json) and url-encoded (application/x-www-form-urlencoded body formats have worked. XML is not working for some reason" }

Acredito que a razão pela qual você deve criar uma classe de modelo de dados é porque valores simples são assumidos como sendo dos parâmetros da URL e um único valor complexo é assumido como sendo do corpo. Eles têm os atributos [FromBody]e [FromUrl], mas o uso [FromBody] string valueainda não funcionou para mim. Parece que eles ainda estão solucionando muitos bugs, então tenho certeza de que isso mudará no futuro.

Edit: Tem XML para trabalhar no corpo. O serializador XML padrão foi alterado para DataContractSerializer em vez de XmlSerializer. Colocar a seguinte linha no meu arquivo Global.asax corrigiu esse problema ( referência )

GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true;
Despertar
fonte
isso funcionou para mim com request.ContentType = "application / json; charset = UTF-8";
Arvind Krmar
15

Após algumas tentativas, acho que o comportamento padrão está correto e não há nada para invadir.

O único truque é: se o argumento do método post for stringcomo abaixo, você deve enviar uma string simples com aspas duplas no corpo (ao usar ajax ou postman), por exemplo,

//send "{\"a\":1}" in body to me, note the outer double quotes
[HttpPost("api1")]
public String PostMethod1([FromBody]string value)
{
    return "received " + value; //  "received {\"a\":1}"
}

Caso contrário, se você enviar uma string json no corpo da postagem sem aspas duplas externas e aspas internas escapadas, poderá ser analisada na classe de modelo (o tipo de argumento), por exemplo,{"a":1, "b":2}

public class MyPoco{
    public int a;
    public int b;
}

//send {"a":1, "b":2} in body to me
[HttpPost("api2")]
public String PostMethod2([FromBody]MyPoco value)
{
    return "received " + value.ToString();  //"received your_namespace+MyPoco"
}
Leon
fonte
11

Eu estava procurando uma solução para esse problema por alguns minutos agora, então vou compartilhar minha solução.

Se você postar um modelo, seu modelo precisará ter um construtor vazio / padrão, caso contrário, o modelo não poderá ser criado, obviamente. Tenha cuidado ao refatorar. ;)

chrjs
fonte
Refatorar é exatamente o que me mordeu aqui, obrigado pela dica!
187 Alan Alan
10

Isso funcionou para mim:

  1. Crie uma classe C # DTO, com uma propriedade para cada atributo que você deseja passar do jQuery / Ajax

    public class EntityData
    {
        public string Attr1 { get; set; }
        public string Attr2 { get; set; }
    }
  2. Defina o método da API da Web:

    [HttpPost()]
    public JObject AddNewEntity([FromBody] EntityData entityData)
    {
  3. Chame a API da Web como tal:

    var entityData = {
        "attr1": "value1",
        "attr2": "value2"
    };
    
    $.ajax({
        type: "POST",
        url: "/api/YOURCONTROLLER/addnewentity",
        async: true,
        cache: false,
        data: JSON.stringify(entityData),
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (response) {
            ...
        }
    });
BigMan73
fonte
Obrigado por postar isso, tentei várias amostras, mas isso funcionou para mim!
Satbir 01/02/19
10

Para aqueles que estão tendo o mesmo problema com o Swagger ou o Postman, como eu, se você estiver passando um atributo simples como string em um post, mesmo com o "ContentType" especificado, você ainda receberá um valor nulo.

Passando apenas:

MyValue

Irá entrar no controlador como nulo.

Mas se você passar:

"MyValue"

O valor vai acertar.

As citações fizeram a diferença aqui. Claro, isso é apenas para Swagger e Postman. Por exemplo, em um aplicativo Frontend usando Angular, isso deve ser resolvido pela estrutura automaticamente.

dvc.junior
fonte
6

Eu tive o mesmo problema e descobri que, ao alterar o Tipo de conteúdo para "application / json", o problema não foi resolvido. No entanto, "application / json; charset = utf-8" funcionou.

byobgyn
fonte
Sim, a API da Web não será desserializada sem o charset = utf-8. blog.codenamed.nl/2015/05/12/…
Sam Rueby 10/18
4

Eu tive um problema semelhante em que o objeto de solicitação para o meu método de API da Web era sempre nulo. Notei que, como o nome da ação do controlador era prefixado com "Get", a API da Web tratava isso como um HTTP GET em vez de um POST. Depois de renomear a ação do controlador, agora funciona como pretendido.

Richard Pursehouse
fonte
3

Com o Angular, eu era capaz de passar dados neste formato:

 data: '=' + JSON.stringify({ u: $scope.usrname1, p: $scope.pwd1 }),
 headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8' }

E no Web API Controler:

    [HttpPost]
    public Hashtable Post([FromBody]string jsonString)
    {
        IDictionary<string, string> data = JsonConvert.DeserializeObject<IDictionary<string, string>>(jsonString);
        string username = data["u"];
        string pwd = data["p"];
   ......

Como alternativa, eu também poderia postar dados JSON como este:

    data: { PaintingId: 1, Title: "Animal show", Price: 10.50 } 

E, no controlador, aceite um tipo de classe como este:

    [HttpPost]
    public string POST(Models.PostModel pm)
    {

     ....
    }

De qualquer maneira, se você tiver uma classe pública estabelecida na API, poste JSON, caso contrário, poste '=' + JSON.stringify ({..: ..., ..: ...})

Yogi
fonte
3

No meu caso, o problema era que o parâmetro era uma string e não um objeto. Alterei o parâmetro para JObject do Newsoft.Json e funciona.

syb
fonte
2

Adicionando linha

        ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());

até o final da função protected void Application_Start()no Global.asax.cs corrigiu um problema semelhante para mim no ASP.NET MVC3.

Sergey Kudriavtsev
fonte
Obrigado pela ajuda, mas infelizmente não ajudou. Por enquanto, manterei a linha, pois pode ajudar de qualquer maneira!
Ianrathbone
Só para acrescentar os mesmos problemas ocorrem quando eu postar XML
ianrathbone
2

Se você estiver usando um DataContractSerializer para o Xml Formatter ou JSON Formatter, precisará se livrar dele. Eu tinha isso no meu arquivo WebApiConfig:

public static void Register(HttpConfiguration config)
{
     config.Routes.MapHttpRoute(
           name: "DefaultApi",
           routeTemplate: "api/{controller}/{id}",
           defaults: new { id = RouteParameter.Optional }
     );    

     var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
     jsonFormatter.UseDataContractJsonSerializer = true;
}

Simplesmente comento jsonFormatter.UseDataContractJsonSerializer = true;e meu parâmetro de entrada não é mais nulo. Agradeço ao 'Despertar' por me dar uma pista.

Amir Chatrbahr
fonte
2

Se você tem certeza sobre o JSON enviado, deve rastrear sua API com cuidado:

  1. Instalar Microsoft.AspNet.WebApi.Tracing pacote
  2. Adicione config.EnableSystemDiagnosticsTracing();a WebApiConfigclasse dentro do Registermétodo.

Agora olhe para a saída Debug e você provavelmente encontrará um inválido ModelState entrada de log .

Se ModelStatefor inválido, você poderá encontrar a causa real em Errors:

Ninguém pode adivinhar essa exceção:

Could not load file or assembly 'Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
Mohsen Afshin
fonte
você salvou minha vida. Ficando nulo como o modelo e depois de instalar o pacote, descobriu que meu JSON não estava no formato correto.
Khizar Iqbal
2

Eu tive o mesmo problema de obter nulo como parâmetro, mas estava relacionado a objetos grandes. Acabou que o problema estava relacionado ao comprimento máximo do IIS. Pode ser configurado em web.config.

  <system.web>
    <httpRuntime targetFramework="4.7" maxRequestLength="1073741824" />
  </system.web>

Gostaria de saber por que a API da Web suprimiu o erro e envia objetos nulos para minhas APIs. Encontrei o erro usando o Microsoft.AspNet.WebApi.Tracing.

mohghaderi
fonte
2

JSON.stringify (...) resolveu meus problemas

ragnarswanson
fonte
1

Sei que essa não é uma resposta para essa pergunta, mas me deparei com ela ao procurar uma solução para o meu problema.

No meu caso, o tipo complexo não estava sendo vinculado, mas eu não estava fazendo um POST, estava fazendo um GET com parâmetros de string de consulta. A solução foi adicionar [FromUri] ao argumento:

public class MyController : ApiController
{
    public IEnumerable<MyModel> Get([FromUri] MyComplexType input)
    {
        // input is not null as long as [FromUri] is present in the method arg
    }
}
danludwig
fonte
Isso ocorre porque o corpo da solicitação é ignorado (e às vezes causa um erro) ao usar GET. O motivo pelo qual agora funciona é porque você está passando parâmetros na string de consulta e seu corpo está vazio , como deve ser em um GET
RyBolt
1

Eu tive o mesmo problema no Fiddler. Eu já tive Content-Type: application/json; charset=utf-8ouContent-Type: application/json no cabeçalho da solicitação.

Meu corpo pedido também foi uma string simples, e em Fiddler eu tinha escrito: {'controller':'ctrl'}. Isso fez com que o parâmetro string no meu método POST fossenull .

Correção : lembre-se de usar aspas, indicando uma string. Ou seja, eu o corrigi escrevendo "{'controller':'ctrl'}". (Nota: ao escrever JSON, certifique-se de usar apóstrofes ou escapar aspas como esta "{\"controller\":\"ctrl\"}":).

gosr
fonte
Eu tive que fazer a mesma coisa no Postman. Mas não preciso fazer isso quando ligo para os serviços Spring. Parece um problema no lado .Net.
Malcolm McRoberts
1

A maneira mais simples que encontrei para lidar com objetos JSON simples que passo no MVC 6 é obter o tipo de parâmetro post como o NewtonSoft jObject:

public ActionResult Test2([FromBody] jObject str)
{
        return Json(new { message = "Test1 Returned: "+ str }); ;
}
Pini Cheyni
fonte
Test ( [FromBody] object body, [FromHeader(Name="Content-Type")] string bodyMediaType) poderia funcionar melhor, pois a verificação bodyMediaType == "application.json"antes da conversão do corpo para o JObject oferece uma oportunidade para alternativas.
VladH
1

A melhor solução para mim é o HTTP completo, como abaixo:

[Route("api/open")]
[HttpPost]
public async Task<string> open(HttpRequestMessage request)
{
    var json = await request.Content.ReadAsStringAsync();
    JavaScriptSerializer jss = new JavaScriptSerializer();            
    WS_OpenSession param = jss.Deserialize<WS_OpenSession>(json);
    return param.sessionid;
}

e desserializando a sequência para o objeto que você espera no corpo da postagem. Para mim, WS_OpenSession é uma classe que continha sessionid, user e key.

Você pode usar o objeto param e acessar suas propriedades.

Muito, muito eficaz.

Eu disse proveniente deste URL:

http://bizcoder.com/posting-raw-json-to-web-api

albertdadze
fonte
1

Para tipos complexos, a API da Web tenta ler o valor do corpo da mensagem, usando um formatador de tipo de mídia.

Por favor, verifique se você tem algum [Serializable] atributo decorando sua classe de modelo.

Remova o atributo para ver se funciona. Isso funcionou para mim.

jaiveeru
fonte
1

Estou um pouco atrasado para a festa, mas qualquer um que tropeçar em um valor NULL passado ao usar um controlador simplesmente adiciona "=" à frente da sua solicitação POST.

O controlador também passou um valor NULL quando usei o application / json Content-Type. Observe o tipo de conteúdo "application / x-www-form-urlencoded" abaixo. O tipo de retorno da API, no entanto, é "application / json".

 public static string HttpPostRequest(string url, Dictionary<string, string> postParameters)
    {
        string postData = "=";

        foreach (string key in postParameters.Keys)
        {
            postData += HttpUtility.UrlEncode(key) + "="
                  + HttpUtility.UrlEncode(postParameters[key]) + ",";
        }

        HttpWebRequest myHttpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
        myHttpWebRequest.Method = "POST";

        byte[] data = System.Text.Encoding.ASCII.GetBytes(postData);

        myHttpWebRequest.ContentType = "application/x-www-form-urlencoded";
        myHttpWebRequest.ContentLength = data.Length;

        Stream requestStream = myHttpWebRequest.GetRequestStream();
        requestStream.Write(data, 0, data.Length);
        requestStream.Close();

        HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();

        Stream responseStream = myHttpWebResponse.GetResponseStream();

        StreamReader myStreamReader = new StreamReader(responseStream, System.Text.Encoding.Default);

        string pageContent = myStreamReader.ReadToEnd();

        myStreamReader.Close();
        responseStream.Close();

        myHttpWebResponse.Close();

        return pageContent;
    }
JTStuedle
fonte
1

não importa que tipo de valor você deseja postar, coloque-o entre aspas para obtê-lo como sequência. Não para tipos complexos.

javascript:

    var myData = null, url = 'api/' + 'Named/' + 'NamedMethod';

    myData = 7;

    $http.post(url, "'" + myData + "'")
         .then(function (response) { console.log(response.data); });

    myData = "some sentence";

    $http.post(url, "'" + myData + "'")
         .then(function (response) { console.log(response.data); });

    myData = { name: 'person name', age: 21 };

    $http.post(url, "'" + JSON.stringify(myData) + "'")
         .then(function (response) { console.log(response.data); });

    $http.post(url, "'" + angular.toJson(myData) + "'")
         .then(function (response) { console.log(response.data); });

c #:

    public class NamedController : ApiController
    {
        [HttpPost]
        public int NamedMethod([FromBody] string value)
        {
            return value == null ? 1 : 0;
        }
    }
Opochitsky Dimitry
fonte
1

Se você colocar a anotação [FromBody] e tiver um objeto Dto como parâmetro no seu método e ainda não conseguir obter os dados, comece a examinar as propriedades e os campos do seu DTO.

Eu tive esse mesmo problema, onde meu DTO estava chegando nulo. Eu achei que o motivo era que uma das propriedades estava apontando para um objeto que não pode ser serializado :( o que faz com que o formatador de mídia falhe na análise dos dados. Portanto, o objeto sempre foi nulo. Espero que ajude outras pessoas também

Possui AlTaiar
fonte
1

Verifique seus tipos de dados. O fichário do modelo dotnet não converterá um float em um número inteiro (e estou assumindo outros conceitos relacionados). Isso fará com que todo o modelo seja rejeitado.

Se você tem json assim:

{
    "shoeSize": 10.5
}

mas seu modelo c # se parece com isso:

class Shoe{
    public int shoeSize;
}

o fichário do modelo rejeitará o modelo e você será nulo.

TwitchBronBron
fonte
1

Estou muito atrasado para isso, mas estava tendo problemas semelhantes e, depois de um dia analisando muitas respostas aqui e obtendo informações, encontrei a solução mais fácil / leve para retornar um ou mais parâmetros a uma API da Web 2. segue:

Isso pressupõe que você saiba como configurar uma ação / controlador de API da Web com roteamento correto, caso contrário, consulte: https://docs.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with -aspnet-web-api / tutorial-seu-primeiro-web-api .

Primeiro, a ação do controlador, esta solução também requer a biblioteca Newtonsoft.Json.

[HttpPost]
public string PostProcessData([FromBody]string parameters) {
    if (!String.IsNullOrEmpty(parameters)) {
        JObject json = JObject.Parse(parameters);

        // Code logic below
        // Can access params via json["paramName"].ToString();
    }
    return "";
}

Lado do cliente usando jQuery

var dataToSend = JSON.stringify({ param1: "value1", param2: "value2"...});
$.post('/Web_API_URI', { '': dataToSend }).done(function (data) {
     console.debug(data); // returned data from Web API
 });

O principal problema que encontrei foi garantir que você envie apenas um único parâmetro geral de volta à API da Web e verifique se ele não tem nome apenas o valor { '': dataToSend } caso contrário, seu valor será nulo no lado do servidor.

Com isso, você pode enviar um ou vários parâmetros para a API da Web em uma estrutura JSON e não precisa declarar nenhum objeto extra no lado do servidor para manipular dados complexos. O JObject também permite que você itere dinamicamente todos os parâmetros passados, permitindo uma escalabilidade mais fácil caso seus parâmetros sejam alterados ao longo do tempo. Espero que ajude alguém que estava lutando como eu.

Nathan
fonte
0

A passagem correta de um único parâmetro no corpo para o WebAPI funciona esse código $.post(url, { '': productId }

E pegá-lo em ação [HttpPost] public ShoppingCartAddRemoveViewModel Delete([FromBody]string value)

A chave é usar a palavra mágica 'valor'. Também pode ser int, ou algum tipo primitivo. Não importa as correções de tipo de conteúdo ou cabeçalho, o Mess é que esse código não funciona na ação de pós-mvc.

Lapenkov Vladimir
fonte