it-swarm.com.de

Der Nachparameter ist immer null

Seit dem Upgrade auf RC für WebAPI habe ich ein echtes seltsames Problem, wenn ich POST auf meiner WebAPI aufrief. So:

public void Post(string value)
{
}

und von Fiddler anrufen:

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

Body:
{
    "value": "test"
}

Beim Debuggen wird der String "value" niemals zugewiesen. Es ist einfach immer NULL . Hat jemand dieses Problem?

(Ich habe das Problem zuerst mit einem komplexeren Typ gesehen)

Das Problem ist nicht nur an ASP.NET MVC 4 gebunden, sondern dasselbe Problem tritt bei einem neuen ASP.NET MVC 3-Projekt nach der RC-Installation auf

184
ianrathbone

Da Sie nur einen Parameter haben, können Sie es mit dem [FromBody]-Attribut dekorieren oder die Methode ändern, um einen DTO mit Wert als Eigenschaft zu akzeptieren, wie ich hier vorgeschlagen habe: MVC4 RC WebApi-Parameterbindung

UPDATE: Die offizielle ASP.NET-Site wurde heute mit einer hervorragenden Erklärung aktualisiert: http://www.asp.net/web-api/overview/working-with-http/sending-html-form-data,-part -1

Kurz gesagt, senden Sie beim Senden eines einzelnen einfachen Typs in den Hauptteil nur den Wert, dem ein Gleichheitszeichen (=) vorangestellt ist, z. Karosserie:

=test

94
Jim Harte

Ich habe mir heute den Kopf darüber gekratzt. 

Meine Lösung besteht darin, den [FromBody] in eine HttpRequestMessage zu ändern, wodurch der HTTP-Stack im Wesentlichen nach oben verschoben wird.

In meinem Fall schicke ich Daten über die Leitung, die mit Json gepackt ist, die dann base64 ist. All dies von einer Android-App. 

Die ursprüngliche Signatur meines Webendpunkts sah folgendermaßen aus (mit [FromBody]):

My original endpoint

Mein Fix für dieses Problem bestand darin, eine HttpRequestMessage für die Signatur meines Endpunkts zu verwenden. 

enter image description here

Sie können dann mit dieser Codezeile auf die Postdaten zugreifen:

enter image description here

Dies funktioniert und ermöglicht Ihnen den Zugriff auf die rohen unberührten Postdaten. Sie müssen sich nicht mit dem Geiger herumspielen, indem Sie ein = Zeichen am Anfang Ihrer Zeichenfolge setzen oder den Inhaltstyp ändern.

Nebenbei habe ich zuerst versucht, einer der obigen Antworten zu folgen, die darin bestand, den Inhaltstyp zu ändern: "Content-Type: application/x-www-form-urlencoded". Für Rohdaten ist dies ein schlechter Ratschlag, da + Zeichen entfernt werden.

Eine Base64-Zeichenfolge, die wie folgt beginnt: "MQ0AAB + LCAAAAAA" endet wie diese "MQ0AAB LCAAAAAA"! Nicht was du willst.

Ein weiterer Vorteil der Verwendung von HttpRequestMessage ist, dass Sie von Ihrem Endpunkt aus auf alle http-Header zugreifen können.

94
Ocean Airdrop

Ich habe gerade mit Fiddler vorgekommen. Das Problem war, dass ich Content-Type nicht angegeben hatte.

Versuchen Sie, einen Header für Content-Type in Ihre POST - Anforderung einzufügen.

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

Alternativ müssen Sie, wie in den Kommentaren unten angegeben, möglicherweise einen JSON-Header einfügen

Content-Type: application/json
68
Kirk Broadhurst

Ich bin auch auf dieses Problem gestoßen und so habe ich mein Problem gelöst

webapi-Code:

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

kundencode:

$.post( "webapi/address", { value: "some value" } );
48
George

Ich benutzte Postman und machte den gleichen Fehler ... das value als json-Objekt anstelle von string übergeben

{
    "value": "test"
}

Der obige Wert ist eindeutigwrong, wenn der Parameter api vom Typ string ist.

Übergeben Sie einfach die Zeichenfolge in doppelte Anführungszeichen im api-Body:

"test"
32
JerryGoyal

Erstellen Sie eine Klasse, die als Datenmodell dient, und senden Sie dann ein JSON-Objekt mit Eigenschaften, die den Eigenschaften Ihrer Datenmodellklasse entsprechen. (Hinweis: Ich habe dies getestet und funktioniert mit der neuesten MVC 4 RC 2012, die ich gerade heruntergeladen habe).

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

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

Das folgende JSON-Objekt wird im HTTP-POST-Body gesendet, der Inhaltstyp ist 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" }

Ich glaube, der Grund, warum Sie eine Datenmodellklasse erstellen müssen, ist, dass angenommen wird, dass einfache Werte aus den URL-Parametern stammen und ein einzelner komplexer Wert aus dem Körper stammt. Sie haben zwar die Attribute [FromBody] und [FromUrl], aber die Verwendung von [FromBody] string value hat für mich immer noch nicht funktioniert. Es sieht so aus, als würden sie immer noch viele Fehler beheben. Ich bin mir sicher, dass sich dies in Zukunft ändern wird.

Edit: XML wurde im Body verwendet. Der Standard-XML-Serialisierer wurde in DataContractSerializer anstelle von XmlSerializer geändert. Durch das Einfügen der folgenden Zeile in meine Global.asax-Datei wurde dieses Problem behoben ( reference )

GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true;
18
Despertar

Nach einigen Versuchen denke ich, dass das Standardverhalten korrekt ist und es nichts zu hacken gibt.

Der einzige Trick ist: Wenn Ihr Post-Methode-Argument wie unten beschrieben string ist, sollten Sie eine einfache Zeichenfolge mit doppelten Anführungszeichen im Hauptteil (bei Verwendung von Ajax oder Postman) senden, z.

//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}"
}

Andernfalls, wenn Sie im Post-Body einen json-String ohne äußere Anführungszeichen und mit Escapezeichen versehene innere Anführungszeichen senden, sollte er in der Modellklasse (dem Argumenttyp) analysiert werden können, z. B. {"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"
}
12
Leon

Ich habe jetzt einige Minuten nach einer Lösung für dieses Problem gesucht, daher teile ich meine Lösung mit. 

Wenn Sie ein Modell bereitstellen, muss Ihr Modell über einen leeren/Standardkonstruktor verfügen, andernfalls kann das Modell nicht erstellt werden. ;)

11
chrjs

Das hat für mich funktioniert:

  1. Erstellen Sie eine C # DTO-Klasse mit einer Eigenschaft für jedes Attribut, das Sie von jQuery/Ajax übergeben möchten

    public class EntityData
    {
        public string Attr1 { get; set; }
        public string Attr2 { get; set; }
    }
    
  2. Definieren Sie die Web-API-Methode:

    [HttpPost()]
    public JObject AddNewEntity([FromBody] EntityData entityData)
    {
    
  3. Rufen Sie das Web-API als solches auf:

    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) {
            ...
        }
    });
    
5
BigMan73

Ich hatte das gleiche Problem und stellte fest, dass das Problem nicht behoben wurde, wenn der Inhaltstyp in "application/json" geändert wurde. "Application/json; charset = utf-8" hat jedoch funktioniert.

5
byobgyn

Ich hatte ein ähnliches Problem, bei dem das Anforderungsobjekt für meine Web-API-Methode immer null war. Mir ist aufgefallen, dass der Controller-Aktionsname mit dem Präfix "Get" vorangestellt wurde. Dies wurde von Web API als HTTP-GET und nicht als POST behandelt. Nach dem Umbenennen der Controller-Aktion funktioniert sie jetzt wie beabsichtigt.

4

Für diejenigen, die das gleiche Problem mit Swagger oder Postman haben wie ich, wenn Sie ein einfaches Attribut als String in einem Beitrag übergeben, selbst wenn der "ContentType" angegeben ist, werden Sie immer noch erhalten ein Nullwert.

Pass nur:

MyValue

Bekomme den Controller als Null.

Aber wenn du bestanden hast:

"MyValue"

Der Wert wird richtig werden.

Die Zitate haben hier den Unterschied gemacht. Natürlich nur für Swagger und Postman. In einer Frontend-App, die Angular verwendet, sollte dies beispielsweise automatisch vom Framework gelöst werden.

4
dvc.junior

In meinem Fall bestand das Problem darin, dass der Parameter eine Zeichenfolge und kein Objekt war. Ich änderte den Parameter in JObject von Newsoft.Json und es funktioniert.

3
syb

Wenn Sie sich bezüglich des gesendeten JSON sicher sind, müssen Sie Ihre API sorgfältig verfolgen:

  1. Microsoft.AspNet.WebApi.Tracing-Paket installieren
  2. Fügen Sie config.EnableSystemDiagnosticsTracing(); in der WebApiConfig-Klasse in der Register-Methode hinzu.

Sehen Sie sich nun die Debug-Ausgabe an und Sie finden wahrscheinlich einen ungültigen ModelState-Protokolleintrag.

Wenn ModelState ungültig ist, können Sie die wahre Ursache in ihrer Errors finden:

Niemand kann eine solche Ausnahme erraten:

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)
2
Mohsen Afshin

Wenn Sie einen DataContractSerializer für Ihren Xml Formatter oder JSON Formatter verwenden, müssen Sie ihn loswerden. 

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;
}

Einfach auskommentieren jsonFormatter.UseDataContractJsonSerializer = true;und meine Eingabeparameter sind nicht mehr null. Danke an 'Despertar' für die Hinweise.

2
Amir Chatrbahr

Zeile hinzufügen

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

zum Ende der Funktion protected void Application_Start() in Global.asax.cs wurde ein ähnliches Problem für mich in ASP.NET MVC3 behoben.

2

Mit Angular konnte ich Daten in diesem Format übergeben:

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

Und im 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"];
   ......

Alternativ könnte ich auch JSON-Daten wie folgt posten:

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

Akzeptieren Sie im Controller einen Klassentyp wie folgt: 

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

     ....
    }

So oder so funktioniert es, wenn Sie über eine etablierte öffentliche Klasse in der API verfügen, geben Sie anschließend JSON ein.

2
Yogi

Ich bin ein wenig zu spät zur Party, aber wer bei der Verwendung eines Controllers über einen NULL-Wert stolpert, fügt einfach "=" vor die POST -Anfrage.

Der Controller hat auch einen NULL-Wert übergeben, wenn ich den application/json Content-Type verwendet habe. Beachten Sie den Inhaltstyp "application/x-www-form-urlencoded" unten. Der Rückgabetyp aus der API lautet jedoch "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;
    }
1
JTStuedle

Die beste Lösung für mich ist die vollständige HTTP-Verbindung:

[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;
}

und dann deserialisiert die Zeichenfolge mit dem Objekt, das Sie im Post-Body erwarten .. __ WS_OpenSession ist für mich eine Klasse, die sessionid, user und key enthält.

Von dort aus können Sie das param-Objekt verwenden und auf dessen Eigenschaften zugreifen.

Sehr effektiv.

Ich habe gesagt aus dieser URL:

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

1
albertdadze

Ich hatte das gleiche Problem, als Parameter null zu erhalten, aber dies hatte mit großen Objekten zu tun. Es stellte sich heraus, dass das Problem auf IIS maximale Länge bezogen war. Es kann in web.config konfiguriert werden.

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

Ich frage mich, warum die Web-API den Fehler unterdrückt und Null-Objekte an meine APIs sendet. Ich habe den Fehler bei Microsoft.AspNet.WebApi.Tracing gefunden.

1
mohghaderi

Ich weiß, dass dies keine Antwort auf diese Frage ist, aber ich bin auf die Suche nach einer Lösung für mein Problem gestoßen.

In meinem Fall wurde der komplexe Typ nicht gebunden, aber ich habe keinen POST durchgeführt, sondern ein GET mit Querystring-Parametern. Die Lösung bestand darin, [FromUri] zu dem Argument hinzuzufügen:

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
    }
}
1
danludwig

Ich bin ziemlich spät dran, hatte aber ähnliche Probleme und nach einem Tag, an dem ich viele Antworten durchgegangen bin und Hintergrundinformationen erhalten habe, habe ich herausgefunden, dass die einfachste/leichteste Lösung einen oder mehrere Parameter an eine Web-API-2-Action zurückgibt folgt:

Dies setzt voraus, dass Sie wissen, wie ein Web-API-Controller/eine Aktion mit korrektem Routing eingerichtet wird. Andernfalls beziehen Sie sich auf: https://docs.Microsoft.com/en-us/aspnet/web-api/overview/getting-started -mit-aspnet-web-api/tutorial-your-first-web-api

Zuerst die Controller-Aktion, diese Lösung erfordert auch die Bibliothek 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 "";
}

Clientseite mit 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
 });

Das Hauptproblem, das ich gefunden habe, war sicherzustellen, dass Sie nur einen einzigen Gesamtparameter an die Web-API zurücksenden und sicherstellen, dass es keinen Namen hat. Nur der Wert { '': dataToSend }. Andernfalls ist Ihr Wert auf der Serverseite null.

Damit können Sie einen oder mehrere Parameter an die Web-API in einer JSON-Struktur senden, und Sie müssen keine zusätzlichen Objekte serverseitig deklarieren, um komplexe Daten verarbeiten zu können. Mit dem JObject können Sie auch alle übergebenen Parameter dynamisch iterieren, um die Skalierbarkeit zu erleichtern, falls sich Ihre Parameter im Laufe der Zeit ändern. Hoffentlich hilft das jemandem, der wie ich zu kämpfen hat.

1
Nathan

Bei komplexen Typen versucht das Web-API, den Wert aus dem Nachrichtentext mit einem Medientyp-Formatierer zu lesen. 

Bitte überprüfen Sie, ob Sie ein [Serializable]-Attribut erhalten haben, das Ihre Modellklasse dekoriert.

Entfernen Sie das Attribut, um zu sehen, ob es funktioniert. Das hat bei mir funktioniert.

1
jaiveeru

Die einfachste Möglichkeit, mit einfachen JSON-Objekten umzugehen, die ich in MVC 6 übergebe, besteht darin, den Typ des Post-Parameters wie NewtonSoft jObject abzurufen:

public ActionResult Test2([FromBody] jObject str)
{
        return Json(new { message = "Test1 Returned: "+ str }); ;
}
1
Pini Cheyni

Ich hatte das gleiche Problem bei Fiddler. Ich hatte bereits Content-Type: application/json; charset=utf-8 oder Content-Type: application/json im Anforderungsheader.

Mein Anfragekörper war auch eine einfache Zeichenfolge, und in Fiddler hatte ich geschrieben: {'controller':'ctrl'}. Dadurch wurde der String-Parameter in meiner POST -Methode null.

Fix : Denken Sie daran, Anführungszeichen zu verwenden, um eine Zeichenfolge anzugeben. Das heißt, ich habe es behoben, indem ich "{'controller':'ctrl'}" schrieb. (Hinweis: Verwenden Sie beim Schreiben von JSON unbedingt Apostrophe oder entfernen Sie die Anführungszeichen wie folgt: "{\"controller\":\"ctrl\"}").

1
eightx2

es spielt keine Rolle, welchen Wert Sie veröffentlichen möchten, schließen Sie ihn einfach in die Anführungszeichen ein, um ihn als String zu erhalten. Nicht für komplexe Typen.

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;
        }
    }
1

Wenn Sie dieses Zeichen '\' in Ihrer json-Abfrage in Postman haben, sollten Sie das Escapezeichen verwenden, wenn Sie das Zeichen '\' im json-Zeichenfolgewert benötigen.

Beispiel:

{
    "path": "C:\\Users\\Test\\Documents\\test.txt"
}
0
Gregory

Die korrekte Übergabe einzelner Parameter in body an WebAPI funktioniert mit diesem Code $.post(url, { '': productId }

Und fangen Sie es in Aktion [HttpPost] public ShoppingCartAddRemoveViewModel Delete([FromBody]string value)

Der Schlüssel ist die Verwendung eines Zauberwortes. Es kann auch int sein oder ein primitiver Typ . Unabhängig von Inhaltstyp- oder Kopfzeilenkorrekturen Chaos ist, dass dieser Code in der MVC-Nachaktion nicht funktioniert.

0

In meinem Fall hat das Dekorieren der Parameterklasse mit dem Attribut [JsonObject(MemberSerialization.OptOut)] von Newtonsoft den Trick ausgeführt. 

Zum Beispiel:

[HttpPost]
[Route("MyRoute")]
public IHttpActionResult DoWork(MyClass args)
{
   ...
}

[JsonObject(MemberSerialization.OptOut)]
public Class MyClass
{
    ...
}
0
jellojam

JSON.stringify (...) hat meine Probleme gelöst

0
ragnarswanson

API:

[HttpPost]
public bool UpdateTicketStatus(Ticket t)
{    
    string Id=t.Id;
}

Modell:

public class Ticket
{
    public int Id { get; set; }
    public string AssignedTo { get; set; }
    public string State { get; set; }
    public string History { get; set; }
}

Mit dem Post-Man-Tool senden Sie den Inhalt als json mit den unten angegebenen Rohdaten. Es klappt

{"Id": "169248", "AssignedTo": "xxxx", "State": "Committed", "History": "test1"}

Bitte stellen Sie sicher, dass Sie Cors aktiviert haben.

[EnableCors(origins: "*", headers: "*", methods: "*")]
    public class TicketController : ApiController
    {
}
0
user3007071

Überprüfen Sie Ihre Datentypen. Der Dotnet-Modellordner konvertiert einen Float nicht in eine Ganzzahl (und ich gehe davon aus, dass andere verwandte Konzepte verwendet werden). Dies führt dazu, dass das gesamte Modell abgelehnt wird. 

Wenn Sie json so haben:

{
    "shoeSize": 10.5
}

aber dein c # -Modell sieht so aus:

class Shoe{
    public int shoeSize;
}

der Modellordner wird das Modell ablehnen und Sie erhalten null.

0
TwitchBronBron

Hoffe das hilft.

Ich schaue in verschiedenen Kommentaren und anderen Foren, mische einige Schnipsel und für mich funktioniert dieser Code ...

... im Controller

public HttpResponseMessage Post([FromBody] string jsonData)
    {
        HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, jsonData);            

        try 
        {
            string jsonString = jsonData.ToString();
            JArray jsonVal = JArray.Parse(jsonString) as JArray;
            dynamic mylist= jsonVal;
            foreach (dynamic myitem in mylist)
            {
                string strClave=string.Empty;
                string strNum=string.Empty;
                string strStatus=string.Empty;

                strClave = myitem.clave;
                strNum=myitem.num;
                strStatus = myitem.status; 
            }

... in der WebApiConfig.cs enthält diese Zeile zur Vermeidung des Nullwerts in der [FromBody] -Variablen var jsonFormatter = config.Formatters.OfType (). First ();

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();  /*this line makes no more null when use [FromBody]*/
}

.... auf der Clientseite ist es wichtig, dass das Gleichheitszeichen vor den serialisierten Daten verkettet wird (string json = "=" + SerialData;)

für seralize verwende ich 

System.Web.Script.Serialization.JavaScriptSerializer serializer = new 
System.Web.Script.Serialization.JavaScriptSerializer();

        List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>();
        Dictionary<string, object> row;
        foreach (DataRow dr in DsCnx.Tables[0].Rows)
        {
            row = new Dictionary<string, object>();
            foreach (DataColumn col in DsCnx.Tables[0].Columns)
            {
                row.Add(col.ColumnName, dr[col]);
            }
            rows.Add(row);
        }
        SerialData= serializer.Serialize(rows);
       PostRequest("http://localhost:53922/api/Demo", SerialData);

dies ist meine PostRequest-Funktion, hier ist der Inhaltstyp, den ich verwende: httpWebRequest.ContentType = "application/x-www-form-urlencoded; charset = utf-8";:

private static string PostRequest(string url, string SerialData)
    {         
        string result = String.Empty;
        HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
        httpWebRequest.ContentType = "application/x-www-form-urlencoded; charset=utf-8";
        httpWebRequest.Method = "POST";

        using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
        {
            string json = "=" + SerialData;  
            streamWriter.Write(json);
            streamWriter.Flush();
            streamWriter.Close();
        }
        try
        {
            using (var response = httpWebRequest.GetResponse() as HttpWebResponse)
            {
                if (httpWebRequest.HaveResponse && response != null)
                {
                    using (var reader = new StreamReader(response.GetResponseStream()))
                    {
                        result = reader.ReadToEnd();
                    }
                }
            }
        }
        catch (WebException e)
        {
            if (e.Response != null)
            {
                using (var errorResponse = (HttpWebResponse)e.Response)
                {
                    using (var reader = new StreamReader(errorResponse.GetResponseStream()))
                    {
                        string error = reader.ReadToEnd();
                        result = error;
                    }
                }

            }
        }

        return result.ToString();

    }

hier sind die Links, wo ich ein Codebeispiel als Referenz gefunden habe:

https://weblog.west-wind.com/posts/2012/Aug/30/User-JSONNET-für-dynamic-JSON-parsing#jobject-and-jarray-in-aspnet-web-api

https://blog.codenamed.nl/2015/05/12/why-your-frombody-parameter-is-always-null/

0
Victor Medel

Wenn Sie die Annotation [FromBody] verwenden und Sie ein Dto-Objekt als Parameter für Ihre Methode haben und die Daten immer noch nicht durchlaufen können, schauen Sie sich die Eigenschaften und Felder Ihres DTOs an. 

Ich hatte das gleiche Problem, als mein DTO null wurde. Ich fand den Grund darin, dass eine der Eigenschaften auf ein-Objekt zeigte, das nicht serialisiert werden kann:(, was dazu führt, dass der Medienformatierer die Daten nicht analysiert. Daher war das Objekt immer null Ich hoffe es hilft auch anderen 

0
Has AlTaiar

Das Problem ist, dass Ihre Aktionsmethode einen einfachen Typ erwartet, d. H. Einen String-Parameterwert. Was Sie anbieten, ist ein Objekt. 

Es gibt 2 Lösungen für Ihr Problem.

  1. Erstellen Sie eine einfache Klasse mit der Eigenschaft " value " und verwenden Sie diese Klasse dann als Parameter. In diesem Fall liest die Bindung des Web-API-Modells das JSON-Objekt aus der Anforderung und bindet es an Ihre "object" -Eigenschaft.

  2. Übergeben Sie einfach den Zeichenfolgewert " test " und es wird funktionieren.

0
Deepak Pathak