Как Xml Documentation для Web Api может включать в себя документацию, выходящую за рамки основного проекта?
Документация по включению интеграции XmlDoc в ваши проекты Web Api, по-видимому, обрабатывает только ситуации, когда все ваши типы API являются частью вашего проекта WebApi. В частности, обсуждается, как перенаправить XML-документацию в App_Data/XmlDocument.xml
и раскомментируйте строку в вашей конфигурации, которая будет использовать этот файл. Это неявно допускает только один файл документации проекта.
Однако в моей настройке у меня есть типы запросов и ответов, определенные в общем проекте "Модели". Это означает, что если у меня определена конечная точка, такая как:
[Route("auth/openid/login")]
public async Task<AuthenticationResponse> Login(OpenIdLoginRequest request) { ... }
куда OpenIdLoginRequest
определяется в отдельном проекте C# примерно так:
public class OpenIdLoginRequest
{
/// <summary>
/// Represents the OpenId provider that authenticated the user. (i.e. Facebook, Google, etc.)
/// </summary>
[Required]
public string Provider { get; set; }
...
}
Несмотря на документы XML, свойства request
параметр не содержит документации при просмотре справочной страницы для конкретной конечной точки (т. е. http://localhost/Help/Api/POST-auth-openid-login
).
Как сделать так, чтобы типы в подпроектах с XML-документацией отображались в XML-документации Web API?
5 ответов
Нет встроенного способа добиться этого. Однако для этого требуется всего несколько шагов:
Включите документацию XML для вашего подпроекта (из свойств / сборки проекта) так же, как для вашего проекта Web API. За исключением этого времени, направьте его прямо к
XmlDocument.xml
так что он генерируется в корневой папке вашего проекта.Измените событие postbuild вашего проекта Web API, чтобы скопировать этот XML-файл в ваш
App_Data
папка:copy "$(SolutionDir)SubProject\XmlDocument.xml" "$(ProjectDir)\App_Data\Subproject.xml"
куда
Subproject.xml
следует переименовать в любое имя вашего проекта плюс.xml
,Следующий открытый
Areas\HelpPage\HelpPageConfig
и найдите следующую строку:config.SetDocumentationProvider(new XmlDocumentationProvider( HttpContext.Current.Server.MapPath("~/App_Data/XmlDocument.xml")));
Это строка, которую вы изначально раскомментировали, чтобы сначала включить XML справочную документацию. Замените эту строку на:
config.SetDocumentationProvider(new XmlDocumentationProvider( HttpContext.Current.Server.MapPath("~/App_Data")));
Этот шаг гарантирует, что
XmlDocumentationProvider
передается каталог, содержащий ваши XML-файлы, а не конкретный XML-файл для вашего проекта.Наконец, измените
Areas\HelpPage\XmlDocumentationProvider
следующими способами:а. Заменить
_documentNavigator
поле с:private List<XPathNavigator> _documentNavigators = new List<XPathNavigator>();
б. Замените конструктор на:
public XmlDocumentationProvider(string appDataPath) { if (appDataPath == null) { throw new ArgumentNullException("appDataPath"); } var files = new[] { "XmlDocument.xml", "Subproject.xml" }; foreach (var file in files) { XPathDocument xpath = new XPathDocument(Path.Combine(appDataPath, file)); _documentNavigators.Add(xpath.CreateNavigator()); } }
с. Добавьте следующий метод ниже конструктора:
private XPathNavigator SelectSingleNode(string selectExpression) { foreach (var navigator in _documentNavigators) { var propertyNode = navigator.SelectSingleNode(selectExpression); if (propertyNode != null) return propertyNode; } return null; }
д. И наконец, исправьте все ошибки компилятора (их должно быть три), приводящие к ссылкам на
_documentNavigator.SelectSingleNode
и удалите_documentNavigator.
часть, так что теперь она вызывает новыйSelectSingleNode
Метод, который мы определили выше.
Этот последний шаг - это то, что модифицирует провайдера документов для поддержки поиска в нескольких документах XML текста справки, а не только основного проекта.
Теперь, когда вы изучите свою справочную документацию, она будет включать XML-документацию по типам в вашем связанном проекте.
Я тоже столкнулся с этим, но я не хотел редактировать или дублировать сгенерированный код, чтобы избежать проблем позже.
Основываясь на других ответах, вот автономный поставщик документации для нескольких источников XML. Просто добавьте это в ваш проект:
/// <summary>A custom <see cref="IDocumentationProvider"/> that reads the API documentation from a collection of XML documentation files.</summary>
public class MultiXmlDocumentationProvider : IDocumentationProvider, IModelDocumentationProvider
{
/*********
** Properties
*********/
/// <summary>The internal documentation providers for specific files.</summary>
private readonly XmlDocumentationProvider[] Providers;
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="paths">The physical paths to the XML documents.</param>
public MultiXmlDocumentationProvider(params string[] paths)
{
this.Providers = paths.Select(p => new XmlDocumentationProvider(p)).ToArray();
}
/// <summary>Gets the documentation for a subject.</summary>
/// <param name="subject">The subject to document.</param>
public string GetDocumentation(MemberInfo subject)
{
return this.GetFirstMatch(p => p.GetDocumentation(subject));
}
/// <summary>Gets the documentation for a subject.</summary>
/// <param name="subject">The subject to document.</param>
public string GetDocumentation(Type subject)
{
return this.GetFirstMatch(p => p.GetDocumentation(subject));
}
/// <summary>Gets the documentation for a subject.</summary>
/// <param name="subject">The subject to document.</param>
public string GetDocumentation(HttpControllerDescriptor subject)
{
return this.GetFirstMatch(p => p.GetDocumentation(subject));
}
/// <summary>Gets the documentation for a subject.</summary>
/// <param name="subject">The subject to document.</param>
public string GetDocumentation(HttpActionDescriptor subject)
{
return this.GetFirstMatch(p => p.GetDocumentation(subject));
}
/// <summary>Gets the documentation for a subject.</summary>
/// <param name="subject">The subject to document.</param>
public string GetDocumentation(HttpParameterDescriptor subject)
{
return this.GetFirstMatch(p => p.GetDocumentation(subject));
}
/// <summary>Gets the documentation for a subject.</summary>
/// <param name="subject">The subject to document.</param>
public string GetResponseDocumentation(HttpActionDescriptor subject)
{
return this.GetFirstMatch(p => p.GetResponseDocumentation(subject));
}
/*********
** Private methods
*********/
/// <summary>Get the first valid result from the collection of XML documentation providers.</summary>
/// <param name="expr">The method to invoke.</param>
private string GetFirstMatch(Func<XmlDocumentationProvider, string> expr)
{
return this.Providers
.Select(expr)
.FirstOrDefault(p => !String.IsNullOrWhiteSpace(p));
}
}
... и включите его в своем HelpPageConfig
с путями к документам XML, которые вы хотите:
config.SetDocumentationProvider(new MultiXmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/App_Data/Api.xml"), HttpContext.Current.Server.MapPath("~/App_Data/Api.Models.xml")));
Еще один упрощенный способ сделать это - объединить XML-файлы. Пример кода в моем ответе ниже:
Страница справки Web Api XML комментарии из более чем 1 файлов
Здесь я приведу ссылку для ответа, которая может вам помочь. Вы можете легко использовать несколько файлов XML для документации.
Страница справки Web Api XML комментарии из более чем 1 файлов
Самый простой способ решить эту проблему - создать папку App_Code на развернутом сервере. Затем скопируйте локально XmlDocument.xml, который находится в папке bin, в папку App_Code.
Я нашел лучшее решение
Перейдите к свойствам вашего решения и на странице Built, Out Put, Documentation XML File просто заполните свою папку данными вашего приложения.
Добавьте строку с файлом, который вы хотите вставить в свою документацию, вот так.
config.SetDocumentationProvider (новый XmlDocumentationProvider( HttpContext.Current.Server.MapPath("~/App_Data/FenixCorporate.API.xml")));
config.SetDocumentationProvider(new XmlDocumentationProvider(
HttpContext.Current.Server.MapPath("~/App_Data/FenixCorporate.Entities.xml")));