Hola a todos, un tema importante al crear nuestros servicios es documentarlos, y esta es una tarea bastante tediosa, sin embargo y para fortuna de muchos (me incluyo) ASP.NET Web API nos ayuda en esta labor generando una página de ayuda y una documentación con tan solo modificar un par de cosillas al proyecto.


Nota: El demo ha sido realizado con Visual Studio 2013, si tienen Visual Studio 2012 deben agregar el paquete Microsoft.AspNet.WebApi.HelpPage

Iniciemos, creamos una nueva aplicación ASP.NET Web Application y luego seleccionamos la plantilla Web API:

create web api

Ahora creamos un nuevo modelo:


public class Client
{
    [JsonProperty(PropertyName = "Id")]
    public int ClientId { get; set; }

    [JsonProperty(PropertyName = "Nombre")]
    public string Name { get; set; }

    [JsonProperty(PropertyName = "Apellido")]
    public string LastName { get; set; }

    [JsonProperty(PropertyName = "Ciudad")]
    public string City { get; set; }

    [JsonIgnore]
    public string Password { get; set; }
}

Luego añadimos un controlador, en este caso con el nombre ClientController, lo importante es añadir la información a cada método, ya que dicha información será utilizada para la documentación de cada acción:


public class ClientController : ApiController
{
    private AppContext db = new AppContext();

    /// <summary>
    /// Get all clients
    /// </summary>
    /// <returns>List of clients</returns>
    public IQueryable<Client> GetClients()
    {
        return db.Clients;
    }

    /// <summary>
    /// Get a client by Id
    /// </summary>
    /// <param name="id">Client id</param>
    /// <returns>One Client</returns>
    [ResponseType(typeof(Client))]
    public IHttpActionResult GetClient(int id)
    {
        Client client = db.Clients.Find(id);
        if (client == null)
        {
            return NotFound();
        }

        return Ok(client);
    }

    /// <summary>
    /// Update a Client
    /// </summary>
    /// <param name="id">Client id</param>
    /// <param name="client">Client to be updated</param>
    /// <returns>>Operation result</returns>
    public IHttpActionResult PutClient(int id, Client client)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        if (id != client.ClientId)
        {
            return BadRequest();
        }

        db.Entry(client).State = EntityState.Modified;

        try
        {
            db.SaveChanges();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!ClientExists(id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }

        return StatusCode(HttpStatusCode.NoContent);
    }

    /// <summary>
    /// Create a new Client
    /// </summary>
    /// <param name="client">Object Client</param>
    /// <returns>Operation result</returns>
    [ResponseType(typeof(Client))]
    public IHttpActionResult PostClient(Client client)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        db.Clients.Add(client);
        db.SaveChanges();

        return CreatedAtRoute("DefaultApi", new { id = client.ClientId }, client);
    }

    /// <summary>
    /// Delete a client by id
    /// </summary>
    /// <param name="id">Client id</param>
    /// <returns>Operation result</returns>
    [ResponseType(typeof(Client))]
    public IHttpActionResult DeleteClient(int id)
    {
        Client client = db.Clients.Find(id);
        if (client == null)
        {
            return NotFound();
        }

        db.Clients.Remove(client);
        db.SaveChanges();

        return Ok(client);
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            db.Dispose();
        }
        base.Dispose(disposing);
    }

    private bool ClientExists(int id)
    {
        return db.Clients.Count(e => e.ClientId == id) > 0;
    }
}


Hasta el momento nada nuevo, pero si nos fijamos bien en la carpeta Areas, encontramos una carpeta HelpPage que será el área encargada de generar la documentación:

Area HelpPage

Allí vamos a la clase HelpPageConfig.cs y descomentariamos la siguiente línea que se encuentra en la función Register:


config.SetDocumentationProvider(new XmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/App_Data/XmlDocument.xml")));

Luego en las propiedades del proyecto, en la opción Build, sección Output marcamos la casilla XML documentation file:

properties

Ahora si ejecutamos y seleccionamos la opción API del menú tenemos el listado de acciones con su descripción, y al seleccionar una en particular vamos al detalle de dicha acción:

doc 1

doc 2

Adicionalmente, si vamos a la ruta App_DataXmlDocument.xml del proyecto, dicho archivo xml contiene la información que se está mostrando en pantalla!

Espero les sea interesante el post, saludos!