Marc Rubiño

ASP.NET, C#, AJAX.NET, JavaScript, etc.

Sobre mi :

  • Marc Rubiño
    LinkedIn Twitter Geeks.ms

    Visitantes:

    Locations of visitors to this page

    Reconocimientos:

Recent Posts

Tags

Community

Email Notifications

Archives

September 2010 - Artículos

ASP. NET MVC como Servicio REST

Cada vez más en nuestras aplicaciones web necesitamos simplificar nuestros desarrollos y adaptar nuestros recursos a las necesidades del momento. Actualmente la web demanda aplicaciones con interfaces ricas y servicios que retornen la mínima información posible para poder ser consumidas directamente desde el cliente con el mínimo esfuerzo posible.

La Aparición de los servicios REST a facilitado en mucho este tipo de demanda en detrimento de los servicios que utilizan SOAP y WSDL.

Porque no utilizar una aplicación ASP.NET MVC como un servicio REST en vez de los clásicos servicios de WCF si se adapta muchísimo mejor a los principios REST.

Principios REST

  1. Utilizar los métodos HTTP de forma Explícita
  2. Exponer Uris intuitivas
  3. Servicios sin estado “stateLess”
  4. Negociación de contenido

Crearé una aplicación MVC para consumir desde un cliente script utilizando JQuery y AJAX para ver que cumple con todas nuestras necesidades.

1. Métodos HTTP de forma Explícita “CRUD”

GET       –>  Consultas

POST    –>  Inserción

PUT      –>  Actualización

DELETE –> Eliminación

Que mejor que MVC para poder supervisar desde el controlador que petición es demandada dependiendo del método HTTP para realizar la acción correcta.

RESTHttp

Como podéis comprobar podemos filtrar la acción dependiendo del tipo de petición de una manera tan simple como es simplemente decorando la acción con un atributo.

2 Uris intuitivas

Esto es otra característica distintiva de MVC sus rutas orientadas a SEO y fáciles de intuir y con su potentísimo enrutador.

 $.ajax({ url: "/Grupos", type: "GET", dataType: "Json" ... 
 $.ajax({ url: "/Grupos", type: "POST", dataType: "Json"... 

Con la misma ruta obtendremos diferentes resultados dependiendo del tipo de petición HTTP, o si lo preferimos podemos personalizar la ruta para facilitar el aprendizaje de las rutas de los recursos.

HTTP GET –> http://TestMVCREST/Grupos

HTTP POST –> http://TestMVCREST/Add/Grupo

3 Servicio sin Estado

Como el propio protocolo HTTP cada llamada será independiente y no se mantendrá el estado dejando esa responsabilidad al cliente que realiza las llamadas.

4 Negociación de Contenido

Por último, es bueno construir los servicios de manera que usen el atributo HTTP Accept del encabezado, en donde el valor de este campo es el tipo MIME. De esta manera los clientes pueden elegir que formato de datos quieren leer y minimiza el acoplamiento de datos entre el servicio y las aplicaciones que lo consumen.

Algunos de los tipos MIME más usados para los servicios web REST son:

MIME-Type

Content-Type

JSON

application/json

XML

application/xml

XHTML

application/xhtml+xml

Esto permite que el servicio sea utilizado por distintos clientes escritos en diferentes lenguajes, corriendo en diversas plataformas y dispositivos.  Para eso he creado un cliente que consumirá el servicio MVC REST desde una página HTML con Jquery y llamadas AJAX.

HTTP GET

Para recuperar los datos de los grupos de usuarios:

Utilizamos la misma llamada AJAX para recuperar los datos, pero especificando en que formato los queremos Json o XML en el parámetro “contentType”.

Cliente AJAX:

function GetGruposJSon() {

  $.ajax({ url: "/Grupos", type: "GET", dataType:"Json", contentType: "application/json",
     success: GetGruposOk, error: GetGruposKO
  });
}
function GetGruposXML() {

  $.ajax({ url: "/Grupos", type: "GET", contentType: "application/xml", dataType: "xml",
    success: GetGruposOk, error: GetGruposKO
  });
}

Servicio REST que devuelve la lista de grupos.

No me entretendré en explicar como devolver el formato dependiendo del contentType, porque Eduard Tomas ya lo explicó perfectamente es esta entrada ASP.NET MVC – Formato de salida según Content-Type

REST1

 

REST21

Los datos en el cliente en formato JSon:

RESTJson

Los datos en el cliente en formato XML:

RESTXML

HTTP POST

Para insertar un nuevo grupo a la lista:

function AddGrupo() {

  var nuevoGrupo = { nombre: "LoNetCamp", origen: "Tarragona", imagen: "" };

  $.ajax({ url: "/Grupos", type: "POST", dataType: "Json", processData: true,
     success: AddGrupoOk, error: AddGrupoKo, data: nuevoGrupo
  });
}

Añadimos los datos como un objeto para que se envíen en el formulario como datos y no en el QueryString, la petición es en la misma ruta pero diferente tipo de petición.

RESTPost

 

Desde nuestro cliente HTML obtendremos acceso a los recursos del servicio MVC REST sin problemas.

RESTOK

Esta práctica es muy útil para consumir los servicios desde clientes web de una forma ligera y con llamadas AJAX, pero hay que tener en cuenta sus limitaciones de seguridad y no es una solución que podamos utilizar para todos nuestros escenarios.

Posted: 15/9/2010 23:13 por Marc Rubiño | con 10 comment(s) |
Archivado en: ,,
[Tip/Trick] ASP.NET MVC & PDF

Uno de las preguntas que se suele encontrar en los foros MSDN  es como mostrar un fichero PDF desde ASP.NET y como últimamente he estado trabajando con MVC y me parece muy interesante voy a mostrar como se puede hacer esto desde el controlador.

Normalmente podemos optar por dos estratégicas a la hora de mostrar un documento PDF.

1. Mostrar un fichero

Si tenemos un fichero pdf que queremos mostrar crearemos un controlador que se encargue de mostrar este recurso.

 

pdf2

Con MVC tenemos un método del controlador que nos facilita muchísimo el trabajo File que se encarga de enviar el contenido de un fichero binario a la respuesta y solo tenemos que indicar el tipo “contentType” para que se muestra correctamente.

public ActionResult GetPDF()
{
  string filename = @"~\Content\jquery.cheatsheet.1.4.pdf";
  return File(filename, "application/pdf", 
                 Server.HtmlEncode(filename));
}

De esta manera podemos mostrar ficheros pdf, exel, word, etc. De una manera facilísima.

pdf1

2. Generar un documento Pdf al vuelo

Para poder mostrar el documento pdf correctamente tendemos que utilizar alguna de las librerías gratuitas que existen en la red y en este ejemplo yo he optado por itextSharp.

pdf3

Crearemos otra acción que generará un documento pdf dinámicamente, de esta manera podremos elegir crear el documento enteramente nosotros por código o utilizar una vista como plantilla para el documento.

Yo he creado una vista parcial “userControl” para generar el documento.

pdf6 pdf4

Describiré un poco el código de esta Acción:

  1:  public ActionResult PDF()
  2:  {    
  3:    ControllerContext context = this.ControllerContext;
  4:    string partialViewName = "PDF";
  5:         
  6:    byte[] buf = null;
  7:    MemoryStream pdfTemp = new MemoryStream();
  8:    ViewEngineResult result = ViewEngines.Engines.FindPartialView(context,
  9:                                 partialViewName);
 10: 
 11:    if (result.View != null)
 12:    {
 13:       string htmlTextView = GetViewToString(context, result);
 14:       iTextSharp.text.Document doc = new iTextSharp.text.Document();
 15:       iTextSharp.text.pdf.PdfWriter writer = 
 16:       iTextSharp.text.pdf.PdfWriter.GetInstance(doc, pdfTemp);
 17:       writer.CloseStream = false;
 18:       doc.Open();
 19:       doc.Add(new iTextSharp.text.Paragraph("Documento PDF al Vuelo"));
 20:       AddHTMLText(doc, htmlTextView);
 21:       doc.Close();
 22: 
 23:       buf = new byte[pdfTemp.Position];
 24:       pdfTemp.Position = 0;
 25:       pdfTemp.Read(buf, 0, buf.Length);
 26:    }
 27:    return File(buf, "application/pdf", "tempPdf.pdf");
 28:  }

8: obtendremos la vista que queremos utilizar como plantilla para el documento pdf.

13: Obtendremos el contenido HTML de la vista como texto. Para eso utilizaremos el método GetViewToString.

16: Guardaremos el documento en memoria “memoryStream” para volcar el resultado posteriormente en la respuesta.

 private string GetViewToString(ControllerContext context, ViewEngineResult result)
 {
    string viewResult = "";
    ViewDataDictionary viewData = new ViewDataDictionary();
    TempDataDictionary tempData = new TempDataDictionary(); 
    StringBuilder sb = new StringBuilder();
    using (StringWriter sw = new StringWriter(sb))
    {
       using (HtmlTextWriter output = new HtmlTextWriter(sw))
       {
          ViewContext viewContext = new ViewContext(context, result.View, viewData, tempData, output);
          result.View.Render(viewContext, output);
       }
       viewResult = sb.ToString();
    }
    return viewResult;
 }

19: Podemos crear el documento por código.

20: Añadiremos el contenido de la vista al documento como texto HTML utilizando el método AddHTMLText().

private void AddHTMLText(iTextSharp.text.Document doc, string html)
{
   List<iTextSharp.text.IElement> htmlarraylist = HTMLWorker.ParseToList(
                   new StringReader(html), null);                
             
   foreach (var item in htmlarraylist)
   {
      doc.Add(item);
   }
}

27: Finalmente retornaremos el documento generado al vuelo como un fichero guardado en memoria.

pdf5

Espero poder seguir haciendo más prácticas de este estilo con MVC, porque me esta gustando mucho ;-)

Posted: 8/9/2010 0:20 por Marc Rubiño | con 9 comment(s)
Archivado en: ,