Div*_*Dan 9 asp.net-mvc asp.net-web-api
使用新的webapi 2.1位.出于某种原因,当我打开帮助页面时,没有任何属性的描述细节,例如
/// <summary>
/// Some summary that shows correct
/// </summary>
[DataContract]
public class MyClass
{
/// <summary>
/// Display something.....
/// </summary>
[DataMember(Name = "Great")]
public string MyGreatProperty { get; set; }
Run Code Online (Sandbox Code Playgroud)
当我打开帮助页面时,我可以看到摘要"显示正确的一些摘要"但是对于此模型的属性,没有任何摘要显示.
webapi 2不支持属性描述吗?
And*_*e L 13
您可以使用IDocumentationProvider的以下实现,它是XmlDocumentationProvider的副本,只需稍作修改即可.
HelpPageConfig.cs中的用法示例:
config.SetDocumentationProvider(new MultipleXmlDocumentationProvider(
HttpContext.Current.Server.MapPath("~/bin/App.DataContracts.XML"),
HttpContext.Current.Server.MapPath("~/bin/App.Controllers.XML")));
Run Code Online (Sandbox Code Playgroud)
MultipleXmlDocumentationProvider类:
public class MultipleXmlDocumentationProvider : IDocumentationProvider, IModelDocumentationProvider
{
private IList<XPathNavigator> _documentNavigators;
private const string TypeExpression = "/doc/members/member[@name='T:{0}']";
private const string MethodExpression = "/doc/members/member[@name='M:{0}']";
private const string PropertyExpression = "/doc/members/member[@name='P:{0}']";
private const string FieldExpression = "/doc/members/member[@name='F:{0}']";
private const string ParameterExpression = "param[@name='{0}']";
/// <summary>
/// Initializes a new instance of the <see cref="XmlDocumentationProvider"/> class.
/// </summary>
/// <param name="documentPaths">List of physical paths to XML documents.</param>
public MultipleXmlDocumentationProvider(params string[] documentPaths)
{
if (!documentPaths.Any())
{
throw new ArgumentNullException("documentPaths");
}
var documents = documentPaths.Where(p => File.Exists(p)).ToList();
_documentNavigators = documents.Select(p => new XPathDocument(p).CreateNavigator()).ToList();
}
public string GetDocumentation(HttpControllerDescriptor controllerDescriptor)
{
XPathNavigator typeNode = GetTypeNode(controllerDescriptor.ControllerType);
return GetTagValue(typeNode, "summary");
}
public virtual string GetDocumentation(HttpActionDescriptor actionDescriptor)
{
XPathNavigator methodNode = GetMethodNode(actionDescriptor);
return GetTagValue(methodNode, "summary");
}
public virtual string GetDocumentation(HttpParameterDescriptor parameterDescriptor)
{
ReflectedHttpParameterDescriptor reflectedParameterDescriptor = parameterDescriptor as ReflectedHttpParameterDescriptor;
if (reflectedParameterDescriptor != null)
{
XPathNavigator methodNode = GetMethodNode(reflectedParameterDescriptor.ActionDescriptor);
if (methodNode != null)
{
string parameterName = reflectedParameterDescriptor.ParameterInfo.Name;
XPathNavigator parameterNode = methodNode.SelectSingleNode(String.Format(CultureInfo.InvariantCulture, ParameterExpression, parameterName));
if (parameterNode != null)
{
return parameterNode.Value.Trim();
}
}
}
return null;
}
public string GetResponseDocumentation(HttpActionDescriptor actionDescriptor)
{
XPathNavigator methodNode = GetMethodNode(actionDescriptor);
return GetTagValue(methodNode, "returns");
}
public string GetDocumentation(MemberInfo member)
{
string memberName = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", GetTypeName(member.DeclaringType), member.Name);
string expression = member.MemberType == MemberTypes.Field ? FieldExpression : PropertyExpression;
string selectExpression = String.Format(CultureInfo.InvariantCulture, expression, memberName);
var propertyNode = _documentNavigators.Select(n => n.SelectSingleNode(selectExpression)).FirstOrDefault(n => n != null);
return GetTagValue(propertyNode, "summary");
}
public string GetDocumentation(Type type)
{
XPathNavigator typeNode = GetTypeNode(type);
return GetTagValue(typeNode, "summary");
}
private XPathNavigator GetMethodNode(HttpActionDescriptor actionDescriptor)
{
ReflectedHttpActionDescriptor reflectedActionDescriptor = actionDescriptor as ReflectedHttpActionDescriptor;
if (reflectedActionDescriptor != null)
{
string selectExpression = String.Format(CultureInfo.InvariantCulture, MethodExpression, GetMemberName(reflectedActionDescriptor.MethodInfo));
return _documentNavigators.Select(n => n.SelectSingleNode(selectExpression)).FirstOrDefault(n => n != null);
}
return null;
}
private static string GetMemberName(MethodInfo method)
{
string name = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", GetTypeName(method.DeclaringType), method.Name);
ParameterInfo[] parameters = method.GetParameters();
if (parameters.Length != 0)
{
string[] parameterTypeNames = parameters.Select(param => GetTypeName(param.ParameterType)).ToArray();
name += String.Format(CultureInfo.InvariantCulture, "({0})", String.Join(",", parameterTypeNames));
}
return name;
}
private static string GetTagValue(XPathNavigator parentNode, string tagName)
{
if (parentNode != null)
{
XPathNavigator node = parentNode.SelectSingleNode(tagName);
if (node != null)
{
return node.Value.Trim();
}
}
return null;
}
private XPathNavigator GetTypeNode(Type type)
{
string controllerTypeName = GetTypeName(type);
string selectExpression = String.Format(CultureInfo.InvariantCulture, TypeExpression, controllerTypeName);
return _documentNavigators.Select(n => n.SelectSingleNode(selectExpression)).FirstOrDefault(n => n != null);
}
private static string GetTypeName(Type type)
{
string name = type.FullName;
if (type.IsGenericType)
{
// Format the generic type name to something like: Generic{System.Int32,System.String}
Type genericType = type.GetGenericTypeDefinition();
Type[] genericArguments = type.GetGenericArguments();
string genericTypeName = genericType.FullName;
// Trim the generic parameter counts from the name
genericTypeName = genericTypeName.Substring(0, genericTypeName.IndexOf('`'));
string[] argumentTypeNames = genericArguments.Select(t => GetTypeName(t)).ToArray();
name = String.Format(CultureInfo.InvariantCulture, "{0}{{{1}}}", genericTypeName, String.Join(",", argumentTypeNames));
}
if (type.IsNested)
{
// Changing the nested type name from OuterType+InnerType to OuterType.InnerType to match the XML documentation syntax.
name = name.Replace("+", ".");
}
return name;
}
}
Run Code Online (Sandbox Code Playgroud)
感谢您提供详细信息。我不确定是否会将此称为 Web API 中的错误,因为它本质上并不依赖于 xml 文件作为文档。例如,如果您安装了 HelpPage,您会注意到一个XmlDocumentationProvider.cs名为Areas\HelpPage. 提供程序的此实现查看单个 xml 文件。
IDocumentationProvider对于您的场景,您可以创建&的自定义实现,IModelDocumentationProvider其中基于 C# 类型,您可以查看不同的 xml 文档文件。您可以重用默认 XmlDocumentationProvider 中的大部分代码。
| 归档时间: |
|
| 查看次数: |
1637 次 |
| 最近记录: |