2016-02-18 20 views
5

Aktualizacja: Zaczynam się zastanawiać, czy to z powodu błędu:Duplikat parametr wyjściowy w Swagger

https://github.com/domaindrivendev/Swashbuckle/issues/590

Ale obejście sugested nie wydaje się rozwiązać mój problem.


Używam Swashbuckle do generowania dokumentacji API dla projektu C# ASP.NET Web API.

Moim celem jest umożliwienie następujący jako prawidłowy adres URL:

/endpoint/items/123/foo?param2=bar 

z wymaganym parametrem (param1) jest ustawiony na "foo" i opcjonalnego parametru (param2) jest ustawiony na "bar". Chciałbym oba parametry zawarte w jednym obiekcie parametru C#. (z innymi opcjonalnymi parametrami, takimi jak param3 i tak dalej). Kilka punktów końcowych będzie używać identycznych parametrów i chciałbym mieć pojedynczy obiekt reprezentujący parametry.

Szczegóły dotyczące Swagger/Swashbuckle to w większości czarne skrzynki i nie jestem w stanie tego rozgryźć. Otrzymuję duplikaty na liście parametrów.

Przykładowy kod do odtworzenia problemu:

// This endpoint is generating documentation the way I would like. 
    [HttpGet] 
    [Route("endpoint1/items/{id}/{param1}")] 
    public string GetDataForParameters(int id, string param1, string param2 = null, string param3 = null) 
    { 
     return string.Format("Params: {1}, {2}, {3}", id, param1, param2, param3); 
    } 

    // This endpoint has the structure I would like, but I get duplicates for param1 in the documentation. 
    [HttpGet] 
    [Route("endpoint2/items/{id}/{param1}")] 
    public string GetDataForParameters(int id, [FromUri(Name = "")]MyParams myParams) 
    { 
     return string.Format("Params: {1}, {2}, {3}", id, myParams.Param1, myParams.Param2, myParams.Param3); 
    } 

    public class MyParams 
    { 
     public string Param1 { get; set;} 
     public string Param2 { get; set;} 
     public string Param3 { get; set;} 
    } 

Z drugiej metodzie, ja otrzyma parametry wewnątrz pojedynczego obiektu. Ale Swagger wyświetla zduplikowany wpis dla "param1".

Zrzut ekranu: Swagger duplicate parameter

Jak mogę Swagger/Swashbuckle nie wyświetlać drugi wpis "param1"?


Powodem posiadania tej struktury jest to, że mam wiele punktów końcowych, które zwracają różne typy danych, ale używają wspólnych parametrów. Niektóre parametry są wymagane (i prt identyfikatora), więc chcielibyśmy uwzględnić te w adresie URL, z opcjonalnymi parametrami w querystringu. Wolałbym, aby wspólny obiekt parametru zawierał parametry wymagane i opcjonalne.

Przykładowy kod utworzony za pomocą aktualizacji Visual Studio 2015 1. Domyślny projekt ASP.NET Web API. Dodanie powyższego kodu do wygenerowanego pliku ValuesController.cs. Zainstalowany pakiet Swashbuckle 5.3.1 + zależności.

+0

drugiego routera zawiera 'param1' jako ciąg zapytań, a także jako członek' MyParams'. Być może to jest powód. –

+0

To jest poprawne - chciałbym, aby parametr param1 był podany w ścieżce adresu URL, a parametr param2 - w querystringu. Zaktualizuje pytanie, aby to wyjaśnić. – PMBjornerud

+0

Aktualizacja: Usunięto moją własną odpowiedź sugerującą JsonIgnore jako obejście tego problemu. To spowodowało, że Swagger wyglądał poprawnie, ale po dalszej inspekcji zauważyłem, że wygenerowany adres URL staje się '/ endpoint2/items/123/{Param1}? Param1 = foo & param2 = bar', który nie jest dozwolony. Wciąż szukam rozwiązania tego. – PMBjornerud

Odpowiedz

1

Aktualizacja: Znaleziono obejście. Jest brzydki:

  1. Wprowadzić jawny duplikat parametru w metodzie.
  2. Dodaj atrybut JsonIgnore do zduplikowanych właściwości w obiekcie parametru.

Swagger następnie pobierze parametr metody i dokumentację dla tego. ASP.Net przydzieli parametry BOTH parametrowi metody i obiektowi parametru, umożliwiając kodowi użycie obiektu parametru.

/// <param name="param1">URL parameters must be documented on this level.</param> 
    [HttpGet] 
    [Route("endpoint2/items/{id}/{param1}")] 
    public string GetDataForParameters(int id, string param1, [FromUri(Name = "")]MyParams myParams) 
    { 
     // the param1 method parameter is a dummy, and not used anywhere. 
     return string.Format("Params: {1}, {2}, {3}", id, myParams.Param1, myParams.Param2, myParams.Param3); 
    } 

    public class MyParams 
    { 
     /// <summary> 
     /// Cannot add documentation here, it will be ignored. 
     /// </summary> 
     [JsonIgnore] 
     public string Param1 { get; set;} 
     /// <summary> 
     /// This is included. Querystring parameters can be documented in this class. 
     /// </summary> 
     public string Param2 { get; set;} 
     public string Param3 { get; set;} 
    } 

Nie będę stosować tego podejścia, będzie to zbyt mylące dla każdego programisty czytającego kod.Niestety, Swagger/Swashbuckle zmuszało mnie do zmiany mojego (w pełni działającego) kodu w celu wygenerowania dokumentacji.

O ile nikt nie może zaproponować odpowiedniego rozwiązania, uważam, że najlepszym rozwiązaniem jest posiadanie parametrów prostej metody.

+0

Twoje obejście problemu zadziałało dla mnie. Aby dokumentacja swashbuckle działała, w params uwzględniana jest wielkość liter. Wartość twojej trasy na akcji powinna zostać zmieniona na [Route ("endpoint2/items/{id}/{Param1}")] –

0

Kiedy Swashbuckle generuje plik swagger.json to wygląda na trasy i parametrów zapytania Więc podczas korzystania Get(string param1, string param2 ..) który automatycznie informuje Swashbuckle które są wymagane parametry te (ponieważ nie są one ustawione na = null)

Podczas korzystania Get([FromUri(Name = "")]MyParams myParams) Swashbuckle szuka adnotacji danych (System.ComponentModel.DataAnnotations) w modelu, aby określić, czy parametr jest wymagany, czy nie.

Set Param1 być wymagane

public class MyParams 
    { 
     [Required] 
     public string Param1 { get; set;} 
     public string Param2 { get; set;} 
     public string Param3 { get; set;} 
    } 
+0

Powoduje to, że duplikat jest również wyświetlany zgodnie z wymaganiami, ale Swagger nadal wyświetla go jako duplikat i generuje trasę podobne do '/ {Param1}? param1 = bar & param1 = bar' – PMBjornerud

+0

zaczynają się martwić, to jest głębszy problem, aktualizując moje pytanie za pomocą linków. – PMBjornerud

+0

@PMBjornerud, dlaczego jest param1 częścią modelu, gdy jest już w parametrach routingu? jeśli nie masz nic przeciwko temu, że pytam: – VisualBean