Nancy e o conteúdo multiparte




O que é a Nancy?

Nancy é uma framework leve para .Net que pode ser uma alternativa interessante à framework ASP.Net MVC.


Limitação

A Nancy não processa pedidos HTTP Hypertext Transfer Protocol PUT ou POST do tipo multipart out of the box, i.e., não lhe é intrínseco.


Solução

Vamos assumir que se pretende processar um verbo POST do protocolo HTTP com JSON JavaScript Object Notation e pelo menos um ficheiro anexo. O content-type deste pedido será multipart/form-data: JSON e dados binários.
Para já, o model binding da Nancy suporta apenas pedidos com content-type application/JSON ou application/XML.

No entanto, esta framework disponibliza a classe HttpMultipart que trata de partir o corpo do pedido em várias partes e detectar os content-type respectivos. Apresenta-se de seguida código para exemplificar:

public class IndexModule : NancyModule
{
    public IndexModule()
    {
        Get["/"] = parameters =>
        {
            return "Demo module";
        };

        Post["/"] = parameters =>
        {
            try
            {
                var contentTypeRegex = new Regex("^multipart/form-data;\\s*boundary=(.*)$", RegexOptions.IgnoreCase);
                System.IO.Stream bodyStream = null;

                if (contentTypeRegex.IsMatch(this.Request.Headers.ContentType))
                {
                    var boundary = contentTypeRegex.Match(this.Request.Headers.ContentType).Groups[1].Value;
                    var multipart = new HttpMultipart(this.Request.Body, boundary);
                    bodyStream = multipart.GetBoundaries().First(b => b.ContentType.Equals("application/json")).Value;
                }
                else
                {
                    // Regular model binding goes here.
                    bodyStream = this.Request.Body;
                }

                var jsonBody = new System.IO.StreamReader(bodyStream).ReadToEnd();

                Console.WriteLine("Got request!");
                Console.WriteLine("Body: {0}", jsonBody);
                this.Request.Files.ToList().ForEach(f => Console.WriteLine("File: {0} {1}", f.Name, f.ContentType));

                return HttpStatusCode.OK;
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error!!!!!! {0}", ex.Message);
                return HttpStatusCode.InternalServerError;
            }
        };
    }
}


Em primeiro lugar verifica-se se o conteúdo é do tipo multipart/form-data através da expressão regular

"^multipart/form-data"


Em seguida extrai-se o elemento boundary que separa as partes contíguas, encontrado pela expressão regular

"\\s*boundary=(.*)"


e passa-se-lo para o objecto HttpMultipart bem como o corpo do pedido

var multipart = new HttpMultipart(this.Request.Body, boundary);


e com este objecto obtém-se, então, o conteúdo JSON

bodyStream = multipart.GetBoundaries().First(b => b.ContentType.Equals("application/json")).Value;


e obtém-se, também, o ficheiro através da propriedade Request.Files

this.Request.Files.ToList().ForEach(f => Console.WriteLine("File: {0} {1}", f.Name, f.ContentType));







fonte: Applandeo Software
Licença CC BY-SA 4.0 Silvia Pinhão Lopes, 6.10.15
Print Friendly and PDF

Sem comentários:

Com tecnologia do Blogger.