我有一个C#web api用于访问F#库.我创建了一个我想要返回的类型的DU,并使用模式匹配来选择哪个返回到c#控制器.
在C#控制器中,如何访问从函数调用返回到F#库的类型的数据?
C#控制器
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#类型
module Types = [] [ ] type ValidResponse = { odata: string; token: string; } [ ] [ ] 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(behaviour.body) Types.Valid (behaviour.statusCode, deserializedAuthenticationResponse) | _ -> let deserializedAuthenticationResponse = JsonConvert.DeserializeObject (behaviour.body) Types.Error (behaviour.statusCode, deserializedAuthenticationResponse)
Mark Seemann.. 5
F#Discriminated Unions被编译为抽象类,每个case都是派生的嵌套类.从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
也不是的情况Error
.在这里,我简单地抛出异常作为示例,但在Web API中,返回500
状态代码可能更合适.
但是,所有这些都说明了为什么在C#中编写和维护控制器的麻烦呢?您可以完全用F#编写ASP.NET Web API.
F#Discriminated Unions被编译为抽象类,每个case都是派生的嵌套类.从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
也不是的情况Error
.在这里,我简单地抛出异常作为示例,但在Web API中,返回500
状态代码可能更合适.
但是,所有这些都说明了为什么在C#中编写和维护控制器的麻烦呢?您可以完全用F#编写ASP.NET Web API.