我想知道从WebApi中的歧视联盟的结果返回干净的json最简单的方法是什么?此用例仅用于业务逻辑,不用于http错误等 - 这些用例在管道中处理并像往常一样返回给用户(404,500等)
例如:
type ServiceResult<'a> = { Message:string; Payload:'a }
type ServiceResponse<'a> =
| Success of ServiceResult<'a>
| Fail of ServiceResult<string>
返回:
{
"Case": "Fail",
"Fields": [
{
"Message": "Error performing business logic, your x is not in the y.",
"Payload": "I just couldnt do it"
}
]
}
...或...
{
"Case": "Success",
"Fields": [
{
"Message": "",
"Payload": { "FirstName": "Johnny", "LastName":"Smith" }
}
]
}
我希望只返回服务结果,如:
{
"Message": "",
"Payload": { "FirstName": "Johnny", "LastName":"Smith" }
}
......或......
{
"Message": "Error during operation due to spite.",
"Payload": "I just couldnt do it"
}
我尝试过IdiomaticDuConverter: https://gist.github.com/isaacabraham/ba679f285bfd15d2f53e
但它没有用。我见过的最接近的是Microsoft.FSharpLu.Json,但它没有MediaTypeFormatter来插入管道。
我知道我可以使用Lu并创建我自己的MediaTypeFormatter,但我觉得必须有一种更简单的方法(就像我缺少的一些Json.Net选项)。
你能指出我正确的方向吗?
谢谢: - )
答案 0 :(得分:3)
虽然可能存在一些极端情况,您回答的返回表示是正确的设计,但一般来说这不是一个好的HTTP API设计。 ASP.NET Web API返回HTTP响应,因此返回
的含义{
"Success": false,
"Message": "Error during operation due to spite.",
"Payload": "I just couldnt do it"
}
是该值作为200 OK
响应的一部分返回。这给客户带来了额外的负担,因为他们现在不仅要处理HTTP错误(这仍然可能发生),而且还不能相信200 OK
实际上意味着成功。
相反,如果出现错误,请返回the appropriate HTTP status code。
这也解决了这个问题,并使您的F#代码易于编写。在Controller中,您基本上可以这样做:
member this.Get() =
let result = // produce the result somehow...
match result with
| Success x -> this.Ok x :> IHttpActionResult
| Fail msg -> this.BadRequest msg :> IHttpActionResult
为简单起见,此示例在400 Bad Request
情况下返回Fail
,但如果此情况表示内部错误,则500 Internal Server Error
可能更合适。
答案 1 :(得分:1)
您可以为ServiceResponse
类型编写custom JSON.NET serializer,只需跳过案例标签并将序列化委托给嵌套ServiceResult
。
这里真正的问题是你为什么会遇到这个问题?您已经在记录中携带成功/失败状态,DU不提供任何其他信息。更重要的是,通过您拥有的设置,您可以轻松地代表看似不合适的状态:
Success <| { Success = false; Message = "necktie"; Payload = "bacon" }
为什么不放弃它并仅传递记录,完全避免序列化问题?