2016-01-03 12 views
5

Mam api C#, którego używam do dostępu do biblioteki F #. Stworzyłem DU typów, które chcę zwrócić, i używam dopasowywania wzorców do wyboru, który powraca do kontrolera C#.Praca z typami F # w C#

W kontrolerze C# w jaki sposób uzyskać dostęp do danych typu, który jest zwracany z wywołania funkcji do biblioteki 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 # Rodzaje

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 # Funkcja

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) 
+2

Istnieje przykład, jak radzić sobie z dyskryminowanymi związkami w języku C# tutaj http://stackoverflow.com/questions/23843142/f-discriminated-union-usage-from-c-sharp. Sugeruje również, że zgodnie z wytycznymi projektowymi F # powinieneś rozważyć ukrycie dyskryminowanej unii z API dostępnego w C#. Kody F # zostaną automatycznie przekonwertowane na instancje odpowiedniego typu 'Tuple <>, więc możesz łatwo zwrócić 3-krotną liczbę z kodu F # i mieć o wiele mniej bólu głowy. – jpe

Odpowiedz

5

F # dyskryminowanych Związki są zestawione jako klas abstrakcyjnych, a każdy przypadek jest pochodnym zagnieżdżone klasy. Z C#, można uzyskać dostęp do przypadków, próbując spuszczonymi wynik z 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("..."); 
} 

Zauważ, że C# kompilator nie wie, że już obsługiwane wszystkich przypadków, więc będziesz musiał dostarczyć gałąź zajmująca się przypadkiem, w którym result nie jest ani Valid ani Error. Tutaj po prostu rzuciłem wyjątek jako przykład, ale w Web API prawdopodobnie bardziej odpowiednie byłoby zwrócenie kodu statusu 500.

Wszystko to powiedziawszy, dlaczego nawet mielibyście problemy z pisaniem i utrzymywaniem kontrolerów w C#? Możesz write an ASP.NET Web API purely in F#.