Working with F # types in C #

I have a C # web api that I use to access the F # library. I created the DU of the types I want to return, and I use pattern matching to select which is returned back to the C # controller.

In a C # controller, how do I access data of the type that is returned from a function call in the F # library?

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); } 

Types F #

 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 

Function 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) 
+5
source share
1 answer

F # Discriminative unions are compiled as abstract classes, each of which is a derived nested class. With C #, you can access cases by trying to compress the result from 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("..."); } 

Note that the C # compiler does not know that you handled all cases, so you need to provide a branch that handles the case when the result is neither Valid nor Error . Here, I just selected an exception as an example, but in the web API it would probably be more appropriate to return a 500 status code.

All that said, however, why are there even problems with writing and maintaining controllers in C #? You can write ASP.NET web APIs only in F # .

+5
source

Source: https://habr.com/ru/post/1239746/


All Articles