我有一个C#web api用于访问F#库。我创建了一个我想要返回的类型的DU,并使用模式匹配来选择哪个返回到c#控制器。
在C#控制器中,如何访问从函数调用返回到F#库的类型的数据?
C#Controller
public HttpResponseMessage Post()
{
var _result = Authentication.GetAuthBehaviour();
//Access item1 of my tuple
var _HTTPStatusCode = (HttpStatusCode)_result.item1;
//Access item2 of my tuple
var _body = (HttpStatusCode)_result.item2;
return base.Request.CreateResponse(_HTTPStatusCode, _body);
}
F#Types
module Types =
[<JsonObject(MemberSerialization=MemberSerialization.OptOut)>]
[<CLIMutable>]
type ValidResponse = {
odata: string;
token: string;
}
[<JsonObject(MemberSerialization=MemberSerialization.OptOut)>]
[<CLIMutable>]
type ErrorResponse = {
code: string;
message: string;
url: string;
}
type AuthenticationResponse =
| Valid of int * ValidResponse
| Error of int * ErrorResponse
F#功能
module Authentication =
open Newtonsoft.Json
let GetAuthBehaviour () =
let behaviour = GetBehaviour.Value.authentication
match behaviour.statusCode with
| 200 ->
let deserializedAuthenticationResponse = JsonConvert.DeserializeObject<Types.ValidResponse>(behaviour.body)
Types.Valid (behaviour.statusCode, deserializedAuthenticationResponse)
| _ ->
let deserializedAuthenticationResponse = JsonConvert.DeserializeObject<Types.ErrorResponse>(behaviour.body)
Types.Error (behaviour.statusCode, deserializedAuthenticationResponse)
答案 0 :(得分:5)
F#Discriminated Unions被编译为抽象类,每个案例都是派生的嵌套类。在C#中,您可以尝试从GetAuthBehaviour
:
public HttpResponseMessage Post()
{
var result = Authentication.GetAuthBehaviour();
var valid = result as Types.AuthenticationResponse.Valid;
if (valid != null)
{
int statusCode = valid.Item1;
Types.ValidResponse body = valid.Item2;
return this.CreateResponse(statusCode, body);
}
var error = result as Types.AuthenticationResponse.Error;
if (error != null)
{
int statusCode = error.Item1;
Types.ErrorResponse body = error.Item2;
return this.CreateResponse(statusCode, body);
}
throw new InvalidOperationException("...");
}
请注意,C#编译器并不知道您已经处理了所有情况,因此您需要提供一个处理result
不是{{Valid
的情况的分支。 1}}也不Error
。在这里,我只是抛出异常作为示例,但在Web API中,返回500
状态代码可能更合适。
尽管如此,为什么甚至会在C#中编写和维护控制器?你可以write an ASP.NET Web API purely in F#。