tmenier / Flurl

Fluent URL builder and testable HTTP client for .NET
https://flurl.dev
MIT License
4.23k stars 387 forks source link

JSON with space in property names is null #763

Closed AlexSchoenfeld closed 1 year ago

AlexSchoenfeld commented 1 year ago

Hi,

I have an issue when I'm receiving a JSON with property names that contain space characters:

using var httpTest = new HttpTest();
var json = """
           {
               "ErrorCode": "0x0",
               "Message": {
                   "MessageId": "1-234567",
                   "My Request": {
                       "Req Number": "1-234567890"
                   }
               }
           }
           """;

httpTest.RespondWith(json);

var result = await "https://localhost/test"
    .PostJsonAsync("{id: '123'}")
    .ReceiveJson<Result>();

Here are the classes with JsonPropertyName set for the names with spaces:

public class Result
{
    public string ErrorCode { get; set; }
    public Message Message { get; set; }
}

public class Message
{
    public string MessageId { get; set; }
    [JsonPropertyName("My Request")]
    public MyRequest MyRequest { get; set; }
}

public class MyRequest
{
    [JsonPropertyName("Req Number")]
    public string ReqNumber { get; set; }
}

As you can see here, MyRequest is always null: image

My only workaround at the moment is to get it as string and then manually do it like this:

...
.ReceiveString()

return JsonSerializer.Deserialize<Result>(jsonString)
tcsaddul commented 1 year ago

Space is not allowed there.

AlexSchoenfeld commented 1 year ago

@tcsaddul I can't change the incoming JSON since it's a 3rd party API we are consuming. Shouldn't it be mapped correctly when we use JsonPropertyName?

tcsaddul commented 1 year ago

But I think that's invalid in JSON specs and it is also invalid as a C# field name.

AlexSchoenfeld commented 1 year ago

But I think that's invalid in JSON specs and it is also invalid as a C# field name.

When I throw it like this into JSONLint it says its valid JSON. Also, when I use JsonSerializer.Deserialize<> it works just fine.

I know that such properties won't work in C#, that's why I added the JsonPropertyName.

tcsaddul commented 1 year ago

Maybe this will help. https://stackoverflow.com/questions/32487483/javascriptserializer-custom-property-name

tmenier commented 1 year ago

@AlexSchoenfeld JsonPropertyName is from .NET's System.Text.Json library. Flurl (3.x and earlier) uses Newtonsoft. Switch to the Newtonsoft equivalent attribute and it should work:

https://www.newtonsoft.com/json/help/html/jsonpropertyname.htm

AlexSchoenfeld commented 1 year ago

@AlexSchoenfeld JsonPropertyName is from .NET's System.Text.Json library. Flurl (3.x and earlier) uses Newtonsoft. Switch to the Newtonsoft equivalent attribute and it should work:

https://www.newtonsoft.com/json/help/html/jsonpropertyname.htm

With the Newtonsoft Attribute JsonProperty it now works, thanks! 👍