2014-06-22 9 views
8

Ho una domanda sulle pagine di aiuto dell'API Web ASP.NET.La pagina della Guida dell'API Web ASP.NET non può elaborare il controllore di tipo generico

Di solito le Pagine di Aiuto in grado di generare il WebAPI da XMLDocumentation Codice Esempio:

public class ValueControllerBase : ApiController 
{ 
    /// <summary> 
    /// Base Do 
    /// </summary> 
    public IEnumerable<string> Do() 
    { 
     return new string[] { "value1", "value2" }; 
    } 
} 

public class ValuesController : ValueControllerBase 
{ 
    /// <summary> 
    /// Testing API 
    /// </summary> 
    public string Get(int id) 
    { 
     return "value"; 
    } 
} 

questo può generare con successo, in questo modo:

API 
GET api/Values/Get/{id} 

Description 
Testing API 

API 
POST api/Values/Do 

Description 
Base Do 

ma se io uso un controller di base generica, non sarà generare il documento API.

Esempio:

public class ValueControllerBase<T> : ApiController 
{ 
    /// <summary> 
    /// Base Do 
    /// </summary> 
    public IEnumerable<string> Do() 
    { 
     return new string[] { "value1", "value2" }; 
    } 
} 

public class ValuesController<String> : ValueControllerBase 
{ 
    /// <summary> 
    /// Testing API 
    /// </summary> 
    public string Get(int id) 
    { 
     return "value"; 
    } 
} 

Se uso il codice nella seconda sezione, Pagine di Aiuto può generare il documento API, ma non genera l'annotazione API. La differenza tra i miei due esempi è che il codice di seconda sezione usa un tipo generico.

API 
GET api/Values/Get/{id} 

Description 
Testing API 

API 
POST api/Values/Do 

Description 
null 

Nel metodo Do(), l'annotazione non visualizza rispetto al primo

C'è qualche soluzione per risolvere questi problemi?

risposta

12

Sono stato in grado di risolvere questo problema modificando un codice nel XmlDocumentationProvider.

Il L'implementazione originale del XmlDocumentationProvider.GetTypeName(Type) è la seguente:

private static string GetTypeName(Type type) 
{ 
    string name = type.FullName; 
    if (type.IsGenericType) 
    { 
     // Format the generic type name to something like: Generic{System.Int32,System.String} 
     Type genericType = type.GetGenericTypeDefinition(); 
     Type[] genericArguments = type.GetGenericArguments(); 
     string genericTypeName = genericType.FullName; 

     // Trim the generic parameter counts from the name 
     genericTypeName = genericTypeName.Substring(0, genericTypeName.IndexOf('`')); 
     string[] argumentTypeNames = genericArguments.Select(t => GetTypeName(t)).ToArray(); 
     name = String.Format(CultureInfo.InvariantCulture, "{0}{{{1}}}", genericTypeName, String.Join(",", argumentTypeNames)); 
    } 
    if (type.IsNested) 
    { 
     // Changing the nested type name from OuterType+InnerType to OuterType.InnerType to match the XML documentation syntax. 
     name = name.Replace("+", "."); 
    } 

    return name; 
} 

Non so perché, ma tentare di creare il nome del tipo per la ricerca xml per includere gli attributi effettivi generici, piuttosto che il generico nome del tipo stesso (ad esempio, creano Nullable {bool} piuttosto che Nullable`1). Solo il nome generico stesso è definito nel file xml.

Una semplice modifica al codice ottiene al nome/riferimento alla documentazione per la classe generica correttamente:

.... 
if (type.IsGenericType) 
{ 
    Type genericType = type.GetGenericTypeDefinition(); 
    name = genericType.FullName; 
} 
.... 

Dopo aver effettuato questo cambiamento, le annotazioni hanno cominciato a visualizzare correttamente per i tipi generici, e per me, questo non ha infranto nient'altro.

+0

D'altra parte, questo rompe ottenere la documentazione sui metodi con parametri nullable. –

+0

@MotlicekPetr L'ho implementato ma non vedo che si interrompa la documentazione dei parametri nullable. Hai un esempio? –

Problemi correlati