c# - tutorial - ASP.NET Web API Genera todos los parámetros del modelo-páginas de ayuda
web api documentation generator (2)
La característica de documentación de MVC Web API recorre sus clases y métodos de API utilizando la reflexión. Esto construirá la estructura de la documentación pero dará como resultado una documentación más o menos vacía (e inútil) a menos que haya agregado comentarios de documentación.
El cuerpo de la documentación se completa utilizando el archivo XML que se genera utilizando /// comentarios de la documentación que tiene una estructura específica que debe seguirse. Eso significa que no puedes llenar tu xml con lo que quieras que muestre, de hecho tiene que estar conectado a algo que está en tu API y debe seguir la estructura de tus clases y propiedades.
Entonces, en su caso, no puede poner la documentación de la propiedad del modelo en un método api. Tienes que ponerlo en el Modelo donde existe la propiedad.
MODELO:
public class TestModel
{
/// <summary>This is the first name </summary>
property String FirstName {get;set;}
/// <summary>This is the surname</summary>
property String Surname {get; set;}
property Boolean Active {get;set;}
}
ACCIÓN:
/// <summary>
/// This is a test action
/// </summary>
/// <param name="model">this is the model</param>
public HttpResponseMessage Post(my.namespace.models.TestModel model)
{
...
}
Modificar páginas de ayuda
Las páginas de Ayuda predeterminadas que se generan automáticamente no incluyen la documentación del Modelo, solo se documentan los métodos de la API. Para mostrar más información sobre los parámetros en su API, se requiere una personalización. Las instrucciones que siguen son una forma de agregar documentación de parámetros.
Crea dos nuevos tipos en Áreas / Página de ayuda / Modelos
public class TypeDocumentation
{
public TypeDocumentation()
{
PropertyDocumentation = new Collection<PropertyDocumentation>();
}
public string Summary { get; set; }
public ICollection<PropertyDocumentation> PropertyDocumentation { get; set; }
}
public class PropertyDocumentation
{
public PropertyDocumentation(string name, string type, string docs)
{
Name = name;
Type = type;
Documentation = docs;
}
public string Name { get; set; }
public string Type { get; set; }
public string Documentation { get; set; }
}
Agregar una nueva propiedad a HelpPageApiModel.cs
public IDictionary<string, TypeDocumentation> ParameterModels{ get; set; }
Crea una nueva interfaz
internal interface IModelDocumentationProvider
{
IDictionary<string, TypeDocumentation> GetModelDocumentation(HttpActionDescriptor actionDescriptor);
}
Modificar XmlDocumentationProvider para implementar la nueva interfaz
public class XmlDocumentationProvider : IDocumentationProvider, IModelDocumentationProvider
{
private const string TypeExpression = "/doc/members/member[@name=''T:{0}'']";
private const string PropertyExpression = "/doc/members/member[@name=''P:{0}'']";
///...
///... existing code
///...
private static string GetPropertyName(PropertyInfo property)
{
string name = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", property.DeclaringType.FullName, property.Name);
return name;
}
public IDictionary<string, TypeDocumentation> GetModelDocumentation(HttpActionDescriptor actionDescriptor)
{
var retDictionary = new Dictionary<string, TypeDocumentation>();
ReflectedHttpActionDescriptor reflectedActionDescriptor = actionDescriptor as ReflectedHttpActionDescriptor;
if (reflectedActionDescriptor != null)
{
foreach (var parameterDescriptor in reflectedActionDescriptor.GetParameters())
{
if (!parameterDescriptor.ParameterType.IsValueType)
{
TypeDocumentation typeDocs = new TypeDocumentation();
string selectExpression = String.Format(CultureInfo.InvariantCulture, TypeExpression, GetTypeName(parameterDescriptor.ParameterType));
var typeNode = _documentNavigator.SelectSingleNode(selectExpression);
if (typeNode != null)
{
XPathNavigator summaryNode;
summaryNode = typeNode.SelectSingleNode("summary");
if (summaryNode != null)
typeDocs.Summary = summaryNode.Value;
}
foreach (var prop in parameterDescriptor.ParameterType.GetProperties())
{
string propName = prop.Name;
string propDocs = string.Empty;
string propExpression = String.Format(CultureInfo.InvariantCulture, PropertyExpression, GetPropertyName(prop));
var propNode = _documentNavigator.SelectSingleNode(propExpression);
if (propNode != null)
{
XPathNavigator summaryNode;
summaryNode = propNode.SelectSingleNode("summary");
if (summaryNode != null) propDocs = summaryNode.Value;
}
typeDocs.PropertyDocumentation.Add(new PropertyDocumentation(propName, prop.PropertyType.Name, propDocs));
}
retDictionary.Add(parameterDescriptor.ParameterName, typeDocs);
}
}
}
return retDictionary;
}
}
Agregue código a HelpPageConfigurationExtension en el método GenerateApiModel
IModelDocumentationProvider modelProvider =
config.Services.GetDocumentationProvider() as IModelDocumentationProvider;
if (modelProvider != null)
{
apiModel.ParameterModels = modelProvider.GetModelDocumentation(apiDescription.ActionDescriptor);
}
Modifique HelpPageApiModel.cshtml y añádalo a la ubicación donde desea que se muestre la documentación del modelo.
bool hasModels = Model.ParameterModels.Count > 0;
if (hasModels)
{
<h2>Parameter Information</h2>
@Html.DisplayFor(apiModel => apiModel.ParameterModels, "Models")
}
Agregue un Models.cshtml a DisplayTemplates
@using System.Web.Http
@using System.Web.Http.Description
@using MvcApplication2.Areas.HelpPage.Models
@model IDictionary<string, TypeDocumentation>
@foreach (var modelType in Model)
{
<h3>@modelType.Key</h3>
if (modelType.Value.Summary != null)
{
<p>@modelType.Value.Summary</p>
}
<table class="help-page-table">
<thead>
<tr>
<th>Property</th>
<th>Description</th>
</tr>
</thead>
<tbody>
@foreach (var propInfo in modelType.Value.PropertyDocumentation)
{
<tr>
<td class="parameter-name"><b>@propInfo.Name</b> (@propInfo.Type)</td>
<td class="parameter-documentation">
<pre>@propInfo.Documentation</pre>
</td>
</tr>
}
</tbody>
</table>
}
Estoy ocupado creando una API web (dentro de una aplicación asp mvc4). Estoy usando la biblioteca sugerida en el sitio asp.net para generar documentación ( http://www.asp.net/web-api/overview/creating-web-apis/creating-api-help-pages ).
Mi problema es que si mi parámetro es un modelo, no puedo especificar qué propiedades contiene el modelo en las páginas de ayuda generadas.
Aquí hay un ejemplo:
MODELO:
public class TestModel
{
property String FirstName {get;set;}
property String Surname {get; set;}
property Boolean Active {get;set;}
}
ACCIÓN:
/// <summary>
/// This is a test action
/// </summary>
/// <param name="model">this is the model</param> <-- this works
/// <param name="FirstName">This is the first name </param> <-- doesn''t work
/// <param name ="model.Surname">This is the surname</param> <-- doesn''t work
public HttpResponseMessage Post(my.namespace.models.TestModel model)
{
...
}
Solo se genera el parámetro para el modelo.
Eché un vistazo al documento xml que se genera para la documentación y agrega los otros parámetros.
<member name="my.namespace.api.Post(my.namespace.models.TestModel)">
<summary>
this is a test action
</summary>
<param name="model>this is the model</param>
<param name="FirstName">This is the first name </param>
<param name="model.Surname">This is the surname</param>
</member>
Pero en las páginas de ayuda solo genera el modelo de parámetros.
Lo he rastreado hasta el método donde obtiene los parámetros del xml.
Collection<ApiDescription> apiDescriptions = config.Services.GetApiExplorer().ApiDescriptions;
Esto se encuentra en HelpPageConfigurationExtentions.cs que se genera automáticamente.
¿Me estoy acercando a esto de la manera incorrecta? ¿Alguien sabe de alguna solución?
Cualquier sugerencia o solución será apreciada.
La respuesta de josant funciona muy bien. Sin embargo, sí descubrí que era un tanto celoso. ¡Descubrí que estaba informando cosas simples como cadenas como modelos y reportándolas como una matriz Char con un campo de longitud!
Solo necesitábamos esto para los modelos, así que agregué este código al final del método GetModelDocumentation:
if (parameterDescriptor.ParameterName == "value" || parameterDescriptor.ParameterName == "model")
{
retDictionary.Add(parameterDescriptor.ParameterName, typeDocs);
}
Ahora solo devuelve detalles de parámetros para tipos no simples.