ASP.NET Страница справки веб-API не может обработать контроллер универсального типа

#c# #asp.net-web-api #asp.net-web-api-helppages

#c# #asp.net-web-api #asp.net-web-api-helppages

Вопрос:

У меня есть вопрос о ASP.NET Страницы помощи веб-API.

Обычно справочные страницы могут генерировать WebAPI с помощью примера кода XMLDocumentation:

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

это может быть успешно сгенерировано следующим образом:

 API
GET api/Values/Get/{id}

Description
Testing API

API
POST api/Values/Do

Description
Base Do
  

но если я использую универсальный базовый контроллер, он не будет генерировать документ API.

Пример:

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

Если я использую код во втором разделе, HelpPages может сгенерировать документ API, но не сгенерирует аннотацию API. Разница между моими двумя примерами заключается только в том, что во втором разделе кода используется универсальный тип.

 API
GET api/Values/Get/{id}  

Description
Testing API

API
POST api/Values/Do

Description
null
  

В методе Do() аннотация не отображается по сравнению с первой

Есть ли какое-либо решение для устранения этих проблем?

Ответ №1:

Я смог решить эту проблему, изменив некоторый код в XmlDocumentationProvider .

Первоначальная реализация XmlDocumentationProvider.GetTypeName(Type) заключается в следующем:

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

Я не знаю почему, но они пытаются создать имя типа для поиска xml, чтобы включить фактические общие атрибуты, а не само имя общего типа (например, они создают Nullable{bool} вместо Nullable`1). В файле xml определено только само общее имя.

Простое изменение кода позволяет правильно называть / ссылаться на документацию для универсального класса:

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

После внесения этого изменения аннотации начали корректно отображаться для общих типов, и для меня это тоже ничего не нарушило.

Комментарии:

1. С другой стороны, это нарушает получение документации по методам с обнуляемыми параметрами.

2. @MotlicekPetr У меня это реализовано, но я не вижу, чтобы это нарушало документацию по обнуляемым параметрам. У вас есть пример?