Return an F# record type as JSON in Azure Functions

梦想与她 提交于 2020-01-22 21:28:25

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!