ASP Web API Help pages - Links to other pages

好久不见. 提交于 2019-12-02 07:33:25
Stuart Moore

I have managed to write something that correctly converts links.

An outline is:

In the Help Controller's constructor create a new Lazy IDictionary mapping between the strings found in the cref (e.g. M:Api.Method.Description(System.String) and the associated 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;
        });

Pass this lazy to the various models that back the pages (you may need to create extra models). I have given them all a base class with the following code:

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

Anywhere in the views that had api.Documentation.Trim() - or Html.Raw(api.Documentation) if you have already followed Web Api Help Page- don't escape html in xml documentation - you now wrap so it becomes

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

You will find that to do this you need to make the various ModelDescriptions inherit from HelpPageModelBase - and pass the parent API models through to them (or the Lazy if easier) but it does work in the end.

I'm not especially happy with this solution; you might find it easier to have some form of static ParseDoc method that uses the default Http Configuration to generate the Lazy (but because of other extensions I've made that doesn't work for my case). If you see better ways of doing it, please share! Hopefully it gives you a starting point.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!