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
Sem comentários: