问题
I'm creating a simple azure function in F#. At the end, I'm returning a record type as JSON. I'm doing something like this:
let y = {Gender = "Woman"; Frequency = 17; Percentage = 100.0}
req.CreateResponse(HttpStatusCode.OK, y);
When I call the function from Postman I'm getting this JSON
{"Gender@":"Woman","Frequency@":17,"Percentage@":100}
It looks like that this is caused by the default serializer (Serializing F# Record type to JSON includes '@' character after each property).
Then I tried to use Newtonsoft.Json. Now, the code looks like this:
req.CreateResponse(HttpStatusCode.OK, JsonConvert.SerializeObject(y));
But now I'm getting this using postman:
"{\"Gender\":\"Woman\",\"Frequency\":17,\"Percentage\":100}"
I'd like to get this response:
{"Gender":"Woman","Frequency":17,"Percentage":100}
How can I get this JSON response? Is there any other way apart from specifying DataMemberAttribute
?
Thanks
回答1:
I don't think you can use JSON.Net (would be nice) because the AzureFunctions infrastructure seems to the Data Contract Serializers
I have just implemented the fix as per Serializing F# Record type to JSON includes '@' character after each property and it works for me if a bit clunkier than you may hope.
I was also struggling to fix this and you got me going in the right direction - Thanks
#r "System.Runtime.Serialization"
open System.Runtime.Serialization
[<DataContract>]
type SearchItem = {
[<field: DataMember(Name="Gender")>]
Gender: string
[<field: DataMember(Name="Frequency")>]
Frequency: int
[<field: DataMember(Name="Percentage")>]
Percentage: float
}
回答2:
I found a super simple way to fix this!
There is an overload to req.CreateResponse()
that takes a JsonMediaTypeFormatter
as a 3rd parameter. This allows us to set the ContractResolver
to one provided by Json.Net.
let jsonFormatter = System.Net.Http.Formatting.JsonMediaTypeFormatter()
jsonFormatter.SerializerSettings.ContractResolver <- Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver()
return req.CreateResponse(HttpStatusCode.OK, { Foo = "Bar" }, jsonFormatter)
回答3:
I'm not 100 % to why you get that response, I think it is because you are actually taking the string of an object and not the actual string. If you do this it will work (I think):
let response = sprintf "%s" JsonConvert.SerializeObject(y)
req.CreateResponse(HttpStatusCode.OK, response)
来源:https://stackoverflow.com/questions/43118406/return-an-f-record-type-as-json-in-azure-functions