Страницы справки ASP Web API - ссылки на другие страницы
Я использую страницы справки Web API, и я хотел бы иметь возможность включать ссылки на другие методы. Я видел из-за того, что теги документации XML не обрабатываются страницами справки Web API 2? что использование
Есть ли какие-либо варианты лучше, чем писать мои собственные ссылки в документации и использовать метод, описанный на странице справки Web Api - не переходите через HTML в документации по xml, чтобы получить эти теги вывод на помощь? Это кажется очень хрупким для любых будущих изменений.
Единственная альтернатива, о которой я мог подумать, - заставить API Explorer запускаться дважды - один раз для кэширования всех различных маршрутов и соответствующих им URL-адресов страниц справки, а второй раз для фактической генерации документации. Но я не уверен, где это зацепить (или, если это вообще возможно)
1 ответ
Мне удалось написать что-то, что правильно конвертирует ссылки.
Схема:
В конструкторе контроллера справки создайте новое сопоставление Lazy IDictionary между строками, найденными в скрипте (например, M:Api.Method.Description(System.String) и ассоциированным ApiDescription.
_methodReferences = new Lazy<IDictionary<string, ApiDescription>>(() => {
var dictionary = new Dictionary<string, ApiDescription>();
var apiExplorer = new ApiExplorer(config);
foreach (var apiDescription in apiExplorer.ApiDescriptions)
{
var descriptor = apiDescription.ActionDescriptor as ReflectedHttpActionDescriptor;
if (descriptor != null)
{
var methodName = string.Format(
@"M:{0}.{1}({2})",
descriptor.MethodInfo.DeclaringType.FullName,
descriptor.MethodInfo.Name,
string.Join(@",",descriptor.GetParameters().Select(x => x.ParameterType.FullName))
);
dictionary[methodName] = apiDescription;
}
}
return dictionary;
});
Передайте это ленивым различным моделям, которые поддерживают страницы (вам может понадобиться создать дополнительные модели). Я дал им всем базовый класс со следующим кодом:
public abstract class HelpPageModelBase
{
private static Regex _seeRegex = new Regex("<see cref=\"([^\"]+)\" />");
private readonly Lazy<IDictionary<string, ApiDescription>> _methodReferences;
protected HelpPageModelBase(Lazy<IDictionary<string, ApiDescription>> methodReferences)
{
_methodReferences = methodReferences;
}
protected HelpPageModelBase(HelpPageModelBase parent)
{
_methodReferences = parent._methodReferences;
}
public string ParseDoc(string documentation, UrlHelper url)
{
if (documentation == null)
{
return null;
}
return _seeRegex.Replace(documentation,
match => {
if (_methodReferences.Value.ContainsKey(match.Groups[1].Value))
{
var descriptor = _methodReferences.Value[match.Groups[1].Value];
return string.Format(@"<a href='{0}'>{1} {2}</a>",
url.Action("Api",
"Help",
new {
apiId = descriptor.GetFriendlyId()
}),
descriptor.HttpMethod.Method,
descriptor.RelativePath
);
}
return "";
});
}
}
В любом месте во взглядах, которые имели api.Documentation.Trim()
- или же Html.Raw(api.Documentation)
если вы уже следили за страницей справки Web Api - не экранируйте html в документации xml - теперь вы переносите ее, чтобы она стала
@Html.Raw(Model.ParseDoc(api.Documentation, Url))
Вы обнаружите, что для этого вам нужно сделать так, чтобы различные ModelDescription наследовали от HelpPageModelBase - и передавать им родительские модели API (или Lazy, если проще), но в конце концов это работает.
Я не особенно доволен этим решением; вам может оказаться проще иметь какую-то статическую форму метода ParseDoc, которая использует конфигурацию Http по умолчанию для генерации Lazy (но из-за других расширений, которые я сделал, это не работает для моего случая). Если вы видите лучшие способы сделать это, пожалуйста, поделитесь! Надеюсь, это даст вам отправную точку.