简体   繁体   中英

Getting payload as null for POST and PUT requests

I made POST and PUT APIs and now I am doing attribute validation,

Model

public class Model 
{
    public string user_identifier { get; set; }
    public string name { get; set; }
}

Payload in postman

{
    "user_identifier": "1234",
    "name": "abcd"
}

It works for this, but when I change the type of user_identifier like,

{
    "user_identifier": 1234,
    "name": "abcd"
}

Postman was giving an automatic 400 error for that attribute, which I don't want because I am doing my own validations, so, I added this to suppress those automatic 400 responses,

services.Configure<ApiBehaviorOptions>(options =>
{
    options.SuppressModelStateInvalidFilter = true;
});

Now, when I pass the payload as,

{
    "user_identifier": 1234,
    "name": "abcd"
}

the payload is considered as null, Can anyone please help me with this problem, and also I think it not good to suppress the automatic responses, an alternative would be appreciated.

Thanks in advance.

The main problem is that when your json is like the below, it's saying that the user_identifier is an int but you're saying it should be a string .

{
    "user_identifier": 1234,
    "name": "abcd"
}

This is the error that gets returned on a newly created api project.

{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "|8c6385fc-4816d0c11a257a60.",
    "errors": {
        "$.user_identifier": [
            "The JSON value could not be converted to System.String. Path: $.user_identifier | LineNumber: 1 | BytePositionInLine: 27."
         ]
    }
}

Once you know that's the problem (assuming you're using ASP.NET Core >= 3.0.0), you can find The JSON value could not be converted to System.Int32 which explains how they moved from Json.NET in ASP.NET Core 3.0.0. One option would be to install Microsoft.AspNetCore.Mvc.NewtonsoftJson and add it in startup services.AddControllers().AddNewtonsoftJson();

In ASP.NET Core 3.0 and later versions, the default JSON serializer is System.Text.Json .

And in following doc, we can find that System.Text.Json does not support Non-string values for string properties , which cause this issue.

https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-migrate-from-newtonsoft-how-to?pivots=dotnet-core-3-1#non-string-values-for-string-properties

To allow non-string JSON values for string properties in ASP.NET Core 3+ project, as @Shoejep mentioned, we can add Newtonsoft.Json (Json.NET) support in our project by installing the Microsoft.AspNetCore.Mvc.NewtonsoftJson package and updating Startup.ConfigureServices to call AddNewtonsoftJson method.

https://docs.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-5.0&tabs=visual-studio#use-newtonsoftjson-in-an-aspnet-core-30-mvc-project

Thanks for all the help everyone.

I was not able to find a way to validate the attribute so that .Net doesn't give an automatic 400 BadRequest response.

I figured out the problem, this was happening because I was getting the payload using [FromBody] PayloadModel payload in the parameter of Post request.

Now, I have changed my approach to take the payload using,

var streamReader = new StreamReader(Request.Body);
string requestBody = await streamReader.ReadToEndAsync();
var payload = JsonConvert.DeserializeObject<PayloadModel>(requestBody);

And modified my model class to,

public class PayloadModel 
{
    [JsonProperty("user_identifier")]
    public string UserIdentifier { get; set; }
    
    [JsonProperty("name")]
    public string name { get; set; }
}

This way, I have a bit more granular level control on payload validation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM