private ConfigSectionNode describe(Type tController, object instance, ApiDocGenerator.ControllerContext apictx, ConfigSectionNode dataRoot, NodeOverrideRules overrideRules) { var cdata = dataRoot.AddChildNode("scope"); var cattr = apictx.ApiDocAttr; var docContent = tController.GetText(cattr.DocFile ?? "{0}.md".Args(tController.Name)); var ctlTitle = MarkdownUtils.GetTitle(docContent); var ctlDescription = MarkdownUtils.GetTitleDescription(docContent); (var drequest, var dresponse) = writeCommon(ctlTitle, ctlDescription, tController, apictx.Generator, cattr, cdata); cdata.AddAttributeNode("uri-base", cattr.BaseUri); cdata.AddAttributeNode("auth", cattr.Authentication); cdata.AddAttributeNode("doc-content", docContent); var allMethodContexts = apictx.Generator.GetApiMethods(tController, apictx.ApiDocAttr); foreach (var mctx in allMethodContexts) { var edata = cdata.AddChildNode("endpoint"); (var mrequest, var mresponse) = writeCommon(null, null, mctx.Method, apictx.Generator, mctx.ApiEndpointDocAttr, edata); var epuri = mctx.ApiEndpointDocAttr.Uri.AsString().Trim(); if (epuri.IsNullOrWhiteSpace()) { // infer from action attribute var action = mctx.Method.GetCustomAttributes <ActionBaseAttribute>().FirstOrDefault(); if (action != null) { epuri = action.Name; } if (epuri.IsNullOrWhiteSpace()) { epuri = mctx.Method.Name; } } if (!epuri.StartsWith("/")) { var bu = cattr.BaseUri.Trim(); if (!bu.EndsWith("/")) { bu += "/"; } epuri = bu + epuri; } edata.AddAttributeNode("uri", epuri); writeCollection(mctx.ApiEndpointDocAttr.Methods, "method", mrequest, ':'); //docAnchor var docAnchor = mctx.ApiEndpointDocAttr.DocAnchor.Default("### " + epuri); edata.AddAttributeNode("doc-content", MarkdownUtils.GetSectionContent(docContent, docAnchor)); //Get all method attributes except ApiDoc var epattrs = mctx.Method .GetCustomAttributes(true) .Where(a => !(a is ApiDocAttribute) && !(a is ActionBaseAttribute)); writeInstanceCollection(epattrs.Where(a => !(a is IInstanceCustomMetadataProvider) || (a is IInstanceCustomMetadataProvider cip && cip.ShouldProvideInstanceMetadata(apictx.Generator, edata))).ToArray(), TYPE_REF, edata, apictx.Generator); writeTypeCollection(epattrs.Select(a => a.GetType()) .Where(t => !apictx.Generator.IsWellKnownType(t)) .Distinct() .ToArray(), TYPE_REF, edata, apictx.Generator);//distinct attr types //todo Get app parameters look for Docs and register them and also permissions var epargs = mctx.Method.GetParameters() .Where(pi => !pi.IsOut && !pi.ParameterType.IsByRef && !apictx.Generator.IsWellKnownType(pi.ParameterType)) .Select(pi => pi.ParameterType).ToArray(); writeTypeCollection(epargs, TYPE_REF, edata, apictx.Generator); } return(cdata); }
private ConfigSectionNode describe(Type tController, object instance, ApiDocGenerator.ControllerContext apictx, ConfigSectionNode dataRoot, NodeOverrideRules overrideRules) { var cdata = dataRoot.AddChildNode("scope"); var cattr = apictx.ApiDocAttr; var docContent = tController.GetText(cattr.DocFile ?? "{0}.md".Args(tController.Name)); var ctlTitle = MarkdownUtils.GetTitle(docContent); var ctlDescription = MarkdownUtils.GetTitleDescription(docContent); (var drequest, var dresponse) = writeCommon(ctlTitle, ctlDescription, tController, apictx.Generator, cattr, cdata); cdata.AddAttributeNode("uri-base", cattr.BaseUri); cdata.AddAttributeNode("auth", cattr.Authentication); cdata.AddAttributeNode("doc-content-tpl", docContent); var allMethodContexts = apictx.Generator.GetApiMethods(tController, apictx.ApiDocAttr); foreach (var mctx in allMethodContexts) { var edata = cdata.AddChildNode("endpoint"); (var mrequest, var mresponse) = writeCommon(null, null, mctx.Method, apictx.Generator, mctx.ApiEndpointDocAttr, edata); var epuri = mctx.ApiEndpointDocAttr.Uri.AsString().Trim(); if (epuri.IsNullOrWhiteSpace()) { // infer from action attribute var action = mctx.Method.GetCustomAttributes <ActionBaseAttribute>().FirstOrDefault(); if (action != null) { epuri = action.Name; } if (epuri.IsNullOrWhiteSpace()) { epuri = mctx.Method.Name; } } if (!epuri.StartsWith("/")) { var bu = cattr.BaseUri.Trim(); if (!bu.EndsWith("/")) { bu += "/"; } epuri = bu + epuri; } edata.AddAttributeNode("uri", epuri); writeCollection(mctx.ApiEndpointDocAttr.Methods, "method", mrequest, ':'); //Get all method attributes except ApiDoc var epattrs = mctx.Method .GetCustomAttributes(true) .Where(a => !(a is ApiDocAttribute) && !(a is ActionBaseAttribute) && !apictx.Generator.IgnoreTypePatterns.Any(ignore => a.GetType().FullName.MatchPattern(ignore)) ); writeInstanceCollection(epattrs.Where(a => !(a is IInstanceCustomMetadataProvider) || (a is IInstanceCustomMetadataProvider cip && cip.ShouldProvideInstanceMetadata(apictx.Generator, edata))).ToArray(), TYPE_REF, edata, apictx.Generator); writeTypeCollection(epattrs.Select(a => a.GetType()) .Where(t => !apictx.Generator.IsWellKnownType(t)) .Distinct() .ToArray(), TYPE_REF, edata, apictx.Generator);//distinct attr types //get method parameters var epargs = mctx.Method.GetParameters() .Where(pi => !pi.IsOut && !pi.ParameterType.IsByRef && !apictx.Generator.IsWellKnownType(pi.ParameterType) && !apictx.Generator.IgnoreTypePatterns.Any(ignore => pi.ParameterType.FullName.MatchPattern(ignore)) ) .Select(pi => pi.ParameterType).ToArray(); writeTypeCollection(epargs, TYPE_REF, edata, apictx.Generator); //docAnchor var docAnchor = mctx.ApiEndpointDocAttr.DocAnchor.Default("### " + epuri); var epDocContent = MarkdownUtils.GetSectionContent(docContent, docAnchor); edata.AddAttributeNode("doc-content-tpl", epDocContent); //finally regenerate doc content expanding all variables epDocContent = MarkdownUtils.EvaluateVariables(epDocContent, (v) => { if (v.IsNullOrWhiteSpace()) { return(v); } //Escape: ``{{a}}`` -> `{a}` if (v.StartsWith("{") && v.EndsWith("}")) { return(v.Substring(1, v.Length - 2)); } if (v.StartsWith("@")) { return($"`{{{v}}}`"); //do not expand TYPE spec here } //else navigate config path return(edata.Navigate(v).Value); }); edata.AddAttributeNode("doc-content", epDocContent); }//all endpoints //finally regenerate doc content expanding all variables for the controller docContent = MarkdownUtils.EvaluateVariables(docContent, (v) => { if (v.IsNullOrWhiteSpace()) { return(v); } //Escape: ``{{a}}`` -> `{a}` if (v.StartsWith("{") && v.EndsWith("}")) { return(v.Substring(1, v.Length - 2)); } if (v.StartsWith("@")) { return($"`{{{v}}}`"); //do not expand TYPE spec here } //else navigate config path return(cdata.Navigate(v).Value); }); cdata.AddAttributeNode("doc-content", docContent); return(cdata); }