1

我正在使用 Web API 帮助页面,我希望能够包含指向其他方法的链接。我从Web API 2 帮助页面没有处理 XML 文档标签?不支持使用 <see cref='...'> 。

有没有比在文档中编写我自己的 <a href='...'> 链接并使用Web Api 帮助页面中描述的方法更好的选择 - 不要在 xml 文档中转义 html来获取这些 <a> 标记输出帮助?对于未来的任何变化,它似乎都非常脆弱。

我能想到的唯一选择是强制 API 资源管理器运行两次——一次缓存所有不同的路由及其相应的帮助页面 URL,第二次实际生成文档。但我不确定在哪里挂钩(或者是否有可能)

4

1 回答 1

4

我设法写了一些正确转换链接的东西。

大纲是:

在帮助控制器的构造函数中,在 cref 中找到的字符串(例如 M:Api.Method.Description(System.String) 和关联的 ApiDescription 之间)创建一个新的 Lazy IDictionary 映射

        _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 帮助页面 - 不要在 xml 文档中转义 html - 现在您将其包装成

@Html.Raw(Model.ParseDoc(api.Documentation, Url))

您会发现要做到这一点,您需要使各种 ModelDescriptions 从 HelpPageModelBase 继承 - 并将父 API 模型传递给它们(或者如果更容易,则传递给 Lazy),但它最终确实有效。

我对这个解决方案不是特别满意;您可能会发现使用某种形式的静态 ParseDoc 方法更容易,该方法使用默认的 Http 配置来生成延迟(但由于我所做的其他扩展不适用于我的情况)。如果您看到更好的方法,请分享!希望它能给你一个起点。

于 2014-10-08T11:19:45.270 回答