0

I have an ASP.NET Core Web API endpoint that receives all null values when called from jQuery/browser, but works perfectly when called from Postman with the exact same JSON payload.

The Problem

When I send a POST request from my front-end (jQuery/TypeScript), all properties in my DTO arrive as null in the backend. However, when I send the exact same JSON from Postman, all values are received correctly.

Backend Controller

[HttpPost("create-book")]
public ObjectResult CreateBook([FromBody] CreateBookDto createBookDto)
{
    try
    {
        var book = createBookDto.ToBook();
        var createdBook = _servicesFactory.BookService.CreateBook(book);
        return Ok(new BookDto().FromBook(createdBook));
    }
    catch (Exception ex)
    {
        return Fail<BookDto>(ex, "Error creating book");
    }
}

Frontend Code (TypeScript/jQuery)

public createBook(bookData: any, callback: Function) {
            const json = typeof bookData === 'string'
        ? bookData
        : JSON.stringify(bookData);

    this.ajaxCall(
        'api/book/create-book',
        HttpMethods.POST,
        json,
        [callback],
        ContentType.ApplicationJson,
        null
    );
}

What I've Verified

  1. The JSON is valid and identical in both cases

  2. Headers are identical

    -same Content-Type
    -same session cookie etc.
    
  3. The response is 200 OK in both cases

  4. Other POST endpoints in the same controller work fine from the browser (e.g., /api/book/property/update

I've added case insensitive option to Startup.cs - just in case. Same result..

        services.AddControllers()
            .AddJsonOptions(options =>
            {
                options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
            });

EDIT: Here's my ajaxCall implementation

public ajaxCall(endpoint: string,
                    method: HttpMethods,
                    content: any,
                    callbacks: Array<Function>, contentType) {
    var self = this;
    $.ajax({
        method: HttpMethods[method],
        url: this._contextPath + endpoint,
        contentType:  contentType === ContentType.ApplicationFormUrlEncoded ? "application/x-www-form-urlencoded; charset=UTF-8" : "application/json; charset=utf-8",
        data: content
    })
        .done(function (apiResponse, textStatus, jqXHR) {
            if(!apiResponse.success && apiResponse.metadata && apiResponse.metadata.errorId){
                self._errorObserver.errorReceived(apiResponse.metadata.message+ ":" + apiResponse.metadata.errorId)
            } else {

                for (let callback of callbacks) {
                    if (callback) {
                        callback(apiResponse);
                    }
                }
            }
        })
        .fail(function (msg) {
            console.log('ajax call http error: ' + msg.status + ' ' + msg.statusText);
            if (msg.status === 401) {
                document.location.href = self._contextPath;
            } else if (msg.status === 0) {
                // call aborted (page was changed?)
            } else {
                //console.log('ajax communication error: ' + msg.status + ' ' + msg.statusText);
            }
        }).always(function () {});
}

Here are the calls from web and postman

call headers

and the JSON looks like this:

{
    "ArtNr":"09764000",
    "OnlineArtNr":null,
    "AutorHrsg":"Ballreich",
    "Titel":"Fallkommentar zum UmwandlungsR",
    "AuflageNr":7,
    "LegalRegulId":null,
    "HerstellerId":null,
    "BemerkProduktStufe":"Titel auf 2025 verschoben, Planung AE steht aus. HINWEIS: Autor schreibt bei 2 Werken mit | SCHWERDTFEGER geht vor |Info 25.01.2024: MS-Abgabe Schwerdtfeger erfolgt Mitte/Ende M..rz als h..ndische (!) Korrektur im Ausdruck (ca. 90 S.)",
    "AktuelleDelays":0,
    "CaDruckauflageVorabschaetzung":300,
    "DruckauflageLVP":0,
    "CaUmfangVorabschaetzung":500,
    "UmfangIST":0,
    "BemerkUebergMSChase":"MS-Bearbeitung und Kontaktaufnahme durch PE soll lt. AE erst nach Abschluss Projekt Schwerdtfeger erfolgen",
    "DruckAnlManuDays":15,
    "AuslieferungTermFix":null,
    "Bruttopreis":null,
    "Subspreis":null,
    "SubspreisGueltBis":null,
    "ProduktgruppeId":null,
    "Bemerkung":null,
    "ALAVerchicktAm":null,
    "ReviewTermin":null,
    "TemplateId":null,
    "InhaltFarbeId":null,
    "InhaltPapierId":null,
    "LeinenmaterialId":null,
    "PraegungId":null,
    "PraegungFarbeId":null,
    "Bemerkungen":null,
    "AkAt":0,
    "CE3":false,
    "ContentFreeze":false,
    "WorkInProgress":true,
    "OutOfPlanning":false
}

EDIT 2: Here are the requests, as requested by comments (in raw format) Web:

curl 'http://localhost:8081/api/book/create-book' \
  -H 'Accept: */*' \
  -H 'Accept-Language: en-GB,en-US;q=0.9,en;q=0.8' \
  -H 'Connection: keep-alive' \
  -H 'Content-Type: application/json; charset=UTF-8' \
  -b 'JSESSIONID=C4A0D7767F6C59F1C38D56BE1A9307AD' \
  -H 'Origin: http://localhost:8081' \
  -H 'Referer: http://localhost:8081/create' \
  -H 'Sec-Fetch-Dest: empty' \
  -H 'Sec-Fetch-Mode: cors' \
  -H 'Sec-Fetch-Site: same-origin' \
  -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36' \
  -H 'X-Requested-With: XMLHttpRequest' \
  -H 'sec-ch-ua: "Google Chrome";v="137", "Chromium";v="137", "Not/A)Brand";v="24"' \
  -H 'sec-ch-ua-mobile: ?0' \
  -H 'sec-ch-ua-platform: "Windows"' \
  --data-raw $'{"ArtNr":"1621256","OnlineArtNr":null,"AutorHrsg":"Ballreich","Titel":"Fallkommentar zum UmwandlungsR","AuflageNr":7,"LegalRegulId":null,"HerstellerId":null,"BemerkProduktStufe":"Titel auf 2025 verschoben, Planung AE steht aus. HINWEIS: Autor schreibt bei 2 Werken mit | SCHWERDTFEGER geht vor |Info 25.01.2024: MS-Abgabe Schwerdtfeger erfolgt Mitte/Ende März als händische (\u0021) Korrektur im Ausdruck (ca. 90 S.)","AktuelleDelays":0,"CaDruckauflageVorabschaetzung":300,"DruckauflageLVP":0,"CaUmfangVorabschaetzung":500,"UmfangIST":0,"BemerkUebergMSChase":"MS-Bearbeitung und Kontaktaufnahme durch PE soll lt. AE erst nach Abschluss Projekt Schwerdtfeger erfolgen","DruckAnlManuDays":15,"AuslieferungTermFix":null,"Bruttopreis":null,"Subspreis":null,"SubspreisGueltBis":null,"ProduktgruppeId":null,"Bemerkung":null,"ALAVerchicktAm":null,"ReviewTermin":null,"TemplateId":null,"InhaltFarbeId":null,"InhaltPapierId":null,"LeinenmaterialId":null,"PraegungId":null,"PraegungFarbeId":null,"Bemerkungen":null,"AkAt":0,"CE3":false,"ContentFreeze":false,"WorkInProgress":true,"OutOfPlanning":false}'

POSTMAN:

curl --location 'http://localhost:5000/api/book/create-book' \
--header 'Content-Type: application/json' \
--header 'Authorization: ••••••' \
--data '{
    "ArtNr":"09764000",
    "OnlineArtNr":null,
    "AutorHrsg":"Ballreich",
    "Titel":"Fallkommentar zum UmwandlungsR",
    "AuflageNr":7,
    "LegalRegulId":null,
    "HerstellerId":null,
    "BemerkProduktStufe":"Titel auf 2025 verschoben, Planung AE steht aus. HINWEIS: Autor schreibt bei 2 Werken mit | SCHWERDTFEGER geht vor |Info 25.01.2024: MS-Abgabe Schwerdtfeger erfolgt Mitte/Ende M..rz als h..ndische (!) Korrektur im Ausdruck (ca. 90 S.)",
    "AktuelleDelays":0,
    "CaDruckauflageVorabschaetzung":300,
    "DruckauflageLVP":0,
    "CaUmfangVorabschaetzung":500,
    "UmfangIST":0,
    "BemerkUebergMSChase":"MS-Bearbeitung und Kontaktaufnahme durch PE soll lt. AE erst nach Abschluss Projekt Schwerdtfeger erfolgen",
    "DruckAnlManuDays":15,
    "AuslieferungTermFix":null,
    "Bruttopreis":null,
    "Subspreis":null,
    "SubspreisGueltBis":null,
    "ProduktgruppeId":null,
    "Bemerkung":null,
    "ALAVerchicktAm":null,
    "ReviewTermin":null,
    "TemplateId":null,
    "InhaltFarbeId":null,
    "InhaltPapierId":null,
    "LeinenmaterialId":null,
    "PraegungId":null,
    "PraegungFarbeId":null,
    "Bemerkungen":null,
    "AkAt":0,
    "CE3":false,
    "ContentFreeze":false,
    "WorkInProgress":true,
    "OutOfPlanning":false
}'}'

A WORKING POST request for property/update (just as an example)

curl 'http://localhost:8081/api/book/property/update' \
  -H 'Accept: */*' \
  -H 'Accept-Language: en-GB,en-US;q=0.9,en;q=0.8' \
  -H 'Connection: keep-alive' \
  -H 'Content-Type: application/json; charset=UTF-8' \
  -b 'JSESSIONID=C4A0D7767F6C59F1C38D56BE1A9307AD' \
  -H 'Origin: http://localhost:8081' \
  -H 'Referer: http://localhost:8081/p1' \
  -H 'Sec-Fetch-Dest: empty' \
  -H 'Sec-Fetch-Mode: cors' \
  -H 'Sec-Fetch-Site: same-origin' \
  -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36' \
  -H 'X-Requested-With: XMLHttpRequest' \
  -H 'sec-ch-ua: "Google Chrome";v="137", "Chromium";v="137", "Not/A)Brand";v="24"' \
  -H 'sec-ch-ua-mobile: ?0' \
  -H 'sec-ch-ua-platform: "Windows"' \
  --data-raw '{"bookId":"1","property":"Book.BM","value":"118","propertyType":"Single"}'
14
  • 1
    Have you checked that it's really the same JSON body that's being sent in both cases? In your browser you can open the dev tools and look at network traffic to get what is being sent. After that you can paste both into a tool like jsondiff to compare them Commented Jun 4 at 12:37
  • 4
    What is ajaxCall? jQuery uses $.ajax(. If the payload can't be converted it means it's not the same. .NET doesn't care where the calls come from. It cares about the content type and the shape of the JSON payload. Right now we don't even know what the request or JSON look like, only your assertion they're the same, which is obviously not the case. At the very least post the POSTMAN request Commented Jun 4 at 12:46
  • 1
    You're adding ; charset=UTF-8 to the Content-Type header in your AJAX request, whereas in postman you are setting only application/json - maybe the server doesn't handle the former correctly? Commented Jun 4 at 13:22
  • 1
    The charset is an issue - application/json is always UTF8. I don't think that would prevent deserialization though. This does show that the calls are not the same Commented Jun 4 at 13:30
  • 1
    How come your postman is targeting port 5000, and your front-end is going to 8081? I expect these to be tested against the same port. Are you hitting breakpoints on your backend when going to port 8081? I wonder because C# .net been using port 5000 as the default for their configuration instead of a random port binding in Entity Framework versions. Commented Jun 7 at 2:29

1 Answer 1

0

json properties must be in camelCase instead of PascalCase. This is the default naming convention in web development

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.