Jos*_*osh 9 documentation asp.net-mvc-4 asp.net-web-api asp.net-web-api-helppages
我有我的web api,我添加了web api帮助页面来自动生成我的文档.它适用于列出我的参数的方法,但我有一个这样的方法:
public SessionResult PostLogin(CreateSessionCommand request)
Run Code Online (Sandbox Code Playgroud)
并且,在我的帮助页面上,它只列出了属性部分中的命令参数.但是,在示例请求部分中,它列出了我的CreateSessionCommand类的所有属性.
参数
名称| 说明| 附加信息
要求| 没有可用的文档.| 在请求正文中定义此参数.
我希望它能列出我CreateSessionCommand班上的所有属性.是否有捷径可寻?
所以,我设法为这个问题设计了一个解决方法,万一有人感兴趣.
在HelpPageConfigurationExtensions.cs中,我添加了以下扩展方法:
public static void AlterApiDescription(this ApiDescription apiDescription, HttpConfiguration config)
{
var docProvider = config.Services.GetDocumentationProvider();
var addParams = new List<ApiParameterDescription>();
var removeParams = new List<ApiParameterDescription>();
foreach (var param in apiDescription.ParameterDescriptions)
{
var type = param.ParameterDescriptor.ParameterType;
//string is some special case that is not a primitive type
//also, compare by full name because the type returned does not seem to match the types generated by typeof
bool isPrimitive = type.IsPrimitive || String.Compare(type.FullName, typeof(string).FullName) == 0;
if (!isPrimitive)
{
var properties = from p in param.ParameterDescriptor.ParameterType.GetProperties()
let s = p.SetMethod
where s.IsPublic
select p;
foreach (var property in properties)
{
var documentation = docProvider.GetDocumentation(new System.Web.Http.Controllers.ReflectedHttpParameterDescriptor()
{
ActionDescriptor = param.ParameterDescriptor.ActionDescriptor,
ParameterInfo = new CustomParameterInfo(property)
});
addParams.Add(new ApiParameterDescription()
{
Documentation = documentation,
Name = property.Name,
Source = ApiParameterSource.FromBody,
ParameterDescriptor = param.ParameterDescriptor
});
}
//since this is a complex type, select it to be removed from the api description
removeParams.Add(param);
}
}
//add in our new items
foreach (var item in addParams)
{
apiDescription.ParameterDescriptions.Add(item);
}
//remove the complex types
foreach (var item in removeParams)
{
apiDescription.ParameterDescriptions.Remove(item);
}
}
Run Code Online (Sandbox Code Playgroud)
这是我使用的参数信息实例类
internal class CustomParameterInfo : ParameterInfo
{
public CustomParameterInfo(PropertyInfo prop)
{
base.NameImpl = prop.Name;
}
}
Run Code Online (Sandbox Code Playgroud)
然后,我们在扩展类中的另一个方法中调用扩展
public static HelpPageApiModel GetHelpPageApiModel(this HttpConfiguration config, string apiDescriptionId)
{
object model;
string modelId = ApiModelPrefix + apiDescriptionId;
if (!config.Properties.TryGetValue(modelId, out model))
{
Collection<ApiDescription> apiDescriptions = config.Services.GetApiExplorer().ApiDescriptions;
ApiDescription apiDescription = apiDescriptions.FirstOrDefault(api => String.Equals(api.GetFriendlyId(), apiDescriptionId, StringComparison.OrdinalIgnoreCase));
if (apiDescription != null)
{
apiDescription.AlterApiDescription(config);
HelpPageSampleGenerator sampleGenerator = config.GetHelpPageSampleGenerator();
model = GenerateApiModel(apiDescription, sampleGenerator);
config.Properties.TryAdd(modelId, model);
}
}
return (HelpPageApiModel)model;
}
Run Code Online (Sandbox Code Playgroud)
必须将用于此的注释添加到控制器方法,而不是类对象的属性.这可能是因为我的对象是外部库的一部分
这应该是@Josh回答的补充.如果您不仅要列出模型类中的属性,还要包含每个属性的文档,则应按如下方式修改Areas/HelpPage/XmlDocumentationProvider.cs文件:
public virtual string GetDocumentation(HttpParameterDescriptor parameterDescriptor)
{
ReflectedHttpParameterDescriptor reflectedParameterDescriptor = parameterDescriptor as ReflectedHttpParameterDescriptor;
if (reflectedParameterDescriptor != null)
{
if (reflectedParameterDescriptor.ParameterInfo is CustomParameterInfo)
{
const string PropertyExpression = "/doc/members/member[@name='P:{0}']";
var pi = (CustomParameterInfo) reflectedParameterDescriptor.ParameterInfo;
string selectExpression = String.Format(CultureInfo.InvariantCulture, PropertyExpression, pi.Prop.DeclaringType.FullName + "." + pi.Prop.Name);
XPathNavigator methodNode = _documentNavigator.SelectSingleNode(selectExpression);
if (methodNode != null)
{
return methodNode.Value.Trim();
}
}
else
{
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;
}
Run Code Online (Sandbox Code Playgroud)
和CustomParameterInfo类也应该保留属性信息:
internal class CustomParameterInfo : ParameterInfo
{
public PropertyInfo Prop { get; private set; }
public CustomParameterInfo(PropertyInfo prop)
{
Prop = prop;
base.NameImpl = prop.Name;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6117 次 |
| 最近记录: |