Skip to main content

Upload de arquivos usando ASP.NET MVC, AJAX e jQuery

É muito fácil de fazer um uploader usando componentes do Bootstrap com barra de progresso

Posted in Tutoriais, C#, ASP.NET, MVC, AJAX

Eu resolvi pegar meu artigo e código antigos pra atualizar. Por exemplo: Enquanto antes eu tinha usado o Visual Studio 2010 pra desenvolver um projeto em MVC3 agora eu estou usando o Visual Studio 2012 pra criar um projeto em ASP.NET MVC4 usando bootstrap e uma versão mais recente de todos os plugins que eu usei antes.

Primeiro passo

Antes de mais nada a gente precisa criar um Model do mesmo jeito que Scott Hanselman criou em seu artigo. Assim temos o nome (Name), tamanho (Length) e tipo (Type) do arquivo que vamos enviar pro servidor:

public class UploadFilesResult
{
	public string Name { getset; }
	public int Length { getset; }
	public string Type { getset; }
}

Segundo passo

Agora nós precisamos de uma Action Method que vai efetivamente pegar o arquivo, tratar e salvar no servidor. Vamos chamar esta Action Method usando o método http POST, pegar a lista de arquivos selecionados e salvar dentro de App_Data. Esta Action Method vai retornar uma string em formato json com o Name, Length and Type dos arquivos:

[HttpPost]
public ContentResult UploadFiles()
{
	var r = new List<ViewDataUploadFilesResult>();
 
	foreach (string file in Request.Files)
	{
		HttpPostedFileBase hpf = Request.Files[file] as HttpPostedFileBase;
		if (hpf.ContentLength == 0)
			continue;
 
		string savedFileName = Path.Combine(Server.MapPath("~/App_Data"), Path.GetFileName(hpf.FileName));
		hpf.SaveAs(savedFileName); // Save the file
 
		r.Add(new ViewDataUploadFilesResult()
		{
			Name = hpf.FileName,
			Length = hpf.ContentLength,
			Type = hpf.ContentType
		});
	}
	// Returns json
	return Content("{\"name\":\"" + r[0].Name + "\",\"type\":\"" + r[0].Type + "\",\"size\":\"" + string.Format("{0} bytes", r[0].Length) + "\"}""application/json");
}

Terceiro passo

Agora precisamos usar um plugin do jQuery chamado jQuery File Upload. Ele já traz nativamente um monte de coisa bacana mas, para simplificar, vamos usar apenas 2 arquivos (além de outros que já estou usando): jquery.fileupload.css and jquery.fileupload.js.

Quarto passo

Com isso a gente precisa de alguma maneira de enviar os arquivos. Isso é o que eu criei - apenas para o upload - mas você pode adaptar para seu projeto:

<div class="container">
	<span class="btn btn-success fileinput-button">
		<i class="glyphicon glyphicon-plus">i>
		<span>Add files...span>
		<input id="fileupload" type="file" name="files[]" multiple>
	span>
	<br />
	<div class="progress">
		<div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width0%;">
			<span class="sr-only">0% completespan>
		div>
	div>
	<br />
	<div class="file_name">div>
	<br />
	<div class="file_type">div>
	<br />
	<div class="file_size">div>
div>

Observe 4 coisas:

  1. Eu não usei nenhum HtmlHelper para criar o form. O motivo disso é a facilidade de se criar um form sem HtmlHelper, sem contar que não precisamos usar os HtmlHelpers o tempo todo;
  2. Eu não estou usando form tag. O plugin toma conta de tudo o que precisamos;
  3. A barra de progresso graças ao bootstrap;
  4. As divs no final. Elas só estão lá pra receber e mostrar o que o json trouxe..

Último passo

Depois de organizarmos é hora de fazer o javascript pra fazer isso tudo funcionar. Eu estou usando o plugin jQuery File Upload chamando a Action method UploadFiles criado no HomeController. Some isso ao evento que coloquei no javascript mostrando o status do upload usando a barra de progresso do bootstrap:

<script type="text/javascript">
	$(document).ready(function () {
		$('#fileupload').fileupload({
			dataType: 'json',
			url: '/Home/UploadFiles',
			autoUpload: true,
			done: function (e, data) {
				$('.file_name').html(data.result.name);
				$('.file_type').html(data.result.type);
				$('.file_size').html(data.result.size);
			}
		}).on('fileuploadprogressall'function (e, data) {
			var progress = parseInt(data.loaded / data.total * 100, 10);
			$('.progress .progress-bar').css('width', progress + '%');
		});
	});
script>

É isso. Agora você está pronto pra colocar esse recurso no seu site. E sem postback!

Você pode baixar o código aqui: jQueryFileUploadMVC4.zip (5.84 MB). Sim, quase 6MB, graças aos packages do NuGet.

Did you like the article?

You can subscribe and get them as soon they are online, share using the buttons bellow or leave a comment.

And you also can share using your favorite social network:

Como inserir vários registros no banco usando Entity Framework?

Ok, é com SqlBulkCopy. Mas como ele pertence ao ADO.NET dá no mesmo

Posted in Tutoriais, Dicas, Entity Framework

O Entity Framework (EF) é um ORM da Microsoft que permite a nós, programadores, desenvolver dentro de um modelo conceitual de dados ao invés de programar direto no banco. Desse modo qualquer alteração feita nos dados durante seu uso no sistema deve ser persistida no banco já que isso não é feito automaticamente. No caso do Entity Framework usaríamos o método SaveChanges.

Para funcionar o EF gera um script SQL para cada ação. Assim, se chamarmos o método AddObject para inserir um objeto Pessoa, um INSERT é gerado e enviado ao banco de dados junto com as propriedades do objeto Pessoa.

E quando vamos adicionar 3.000 registros de uma vez?

Nesse caso temos 2 soluções:

  1. Fazemos um loop e jogamos 3.000 INSERTs no banco de dados (não recomendado)
  2. Usamos a classe SqlBulkCopy

Opa, peraê: Quer dizer que não vamos usar o Entity Framework então?

O Entity Framework não tem uma maneira nativa de se fazer um bulk insert. Mas como ele foi construído sobre o ADO.NET não teria problema usarmos o SqlBulkCopy. Isso sem contar o fato que o SqlBulkCopy traz pra gente um ganho considerável de performance com relação aos múltiplos INSERTs.

Veja um exemplo do uso do SqlBulkCopy:

using (SqlConnection destinationConnection = new SqlConnection(connectionString))
{
	destinationConnection.Open();
 
	using (SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnection))
	{
		bulkCopy.DestinationTableName = "dbo.BulkCopyDemoMatchingColumns";
 
		try
		{
			//O reader é um SqlDataReader que recebeu todos os 3.000 registros anteriormente
			bulkCopy.WriteToServer(reader);
		}
		catch (Exception ex)
		{
			Console.WriteLine(ex.Message);
		}
		finally
		{
			reader.Close();
		}
	}
}

O fato da gente precisar usar o SqlBulkCopy não quer dizer que o Entity Framework é ruim. Digamos que a Microsoft “esqueceu” de adicionar essa feature no EF...

Did you like the article?

You can subscribe and get them as soon they are online, share using the buttons bellow or leave a comment.

And you also can share using your favorite social network:

Como corrigir o erro "Error in processing. The server response was: Greylisted, please try again in X seconds"

Exatamente, a solução pra esse erro bizarro. Quantas vezes você já viu esse erro?

Posted in Tutoriais, C#, Dicas, ASP.NET

Eu tive uma sexta-feira interessante. Foi o último dia com uma turma onde eu tive que substituir o instrutor. Eles tiveram alguns problemas com ele e eu fui o escolhido para a substituição. Tudo correu bem. Depois eu fui olhar o log de erros do meu blog (eu uso Elmah, a propósito) e vi um erro que nunca tinha visto antes:

System.Net.Mail.SmtpException
Error in processing. The server response was: Greylisted, please try again in 240 seconds

O tempo varia mas, depois de procurar no google por alguns instantes, achei a solução. Meu servidor tinha implementado algo chamado Greylisting que, de acordo com a Wikipedia, é uma maneira de defender os usuários de e-mail contra spam. Logo, e-mails não reconhecidos pelo sistema são automaticamente rejeitados por um tempo.

Como corrigir?

Tudo que precisei fazer foi criar uma conta de e-mail no meu servidor e adiciona-la no meu web.config da seguinte maneira:

<system.net>
	<mailSettings>
		<smtp>
			<network defaultCredentials="false" host="Mail@DomainName.com" port="25" userName="username@DomainName.com" password="ThisIsAPassword"/>
		smtp>
	mailSettings>
system.net>

Obviamente você precisa colocar seu próprio host, username e password. :-)

E é isso.

Em tempo: A solução eu achei aqui here.

	<system.net>
		<mailSettings>
			<smtp>
				<network defaultCredentials="false" host="mail.davidsonsousa.net" port="25" userName="contact@davidsonsousa.net" password="D#sousa12"/>
			smtp>
		mailSettings>
	system.net>

Did you like the article?

You can subscribe and get them as soon they are online, share using the buttons bellow or leave a comment.

And you also can share using your favorite social network:

Redimentione imagens com CSS mantendo a proporção

Redimensione imagens para qualquer resolução usando somente CSS. Perfeito para layouts fluidos!

Posted in Tutoriais, Dicas, CSS

Quando eu estava criando o blog eu não estava exatamente pensando em dispositivos móveis (celulares e afins). Na verdade eu pensava apenas em publicar o site para poder começar a escrever. Ao passar dos dias eu comecei a fazer alguns testes com o Opera Mobile Emulator e eu pude notar que meu blogestava horrendo nele. Alguns ajustes depois e tudo estava perfeito.

Até eu escrever este post.

O problema era: As imagens são publicadas usando o tamanho original que, normalmente, são maiores que o container. Para resolver esse problema eu poderia simplesmente redimensionar as imagens para que tenham a mesma largura do container. Mas e se o layout for fluido? E se a imagem também for usada em dispositivos móveis? [more]

A solução foi simples: Colocar o max-width em 90%.

#content article img { max-width:90%; }

Neste caso, a div #content e o elemento article (HTML5, alguém?) podem ter qualquer largura já que a imagem vai redimensionar automaticamente para 90% deles. Isso significa que se a largura da imagem tiver menos que 90% do tamanho do container ela não será redimensionada. Agora o mais importante: A proporção da imagem não muda, como você pode ver no print do emulador abaixo.

Essa foi a solução perfeita para o meu blog mas também pode ajudar em websites onde não temos controle sobre o tamanho das imagens que se serão publicadas.

Did you like the article?

You can subscribe and get them as soon they are online, share using the buttons bellow or leave a comment.

And you also can share using your favorite social network:

O que é e como instalar pacotes usando o NuGet usando o Visual Studio 2010?

Aprenda como é fácil e rápido instalar bibliotecas usando o NuGet no Visual Studio 2010

Posted in Tutoriais, Visual Studio

Hoje vou falar de uma extensão do Visual Studio que é uma mão na roda para nós: O NuGet.

O que é?

O NuGet (não confundir com nugget) é uma extensão do Visual Studio que facilita o gerenciamento de bibliotecas open source e ferramentas no Visual Studio. Em termos práticos isso facilita muito na hora de adicionar referências em um projeto e mantê-las atualizadas.

Exemplo: Você está desenvolvendo um projeto que precisa usar Json e achou uma biblioteca incrível (Json.NET) que pode te ajudar a serializar as List<> para que você possa retornar tudo no formato Json. Diante deste cenário você tem praticamente duas escolhas: 1) Adiciona a referência e a atualiza manualmente sempre que sair uma nova versão; 2) Instalar via NuGet e deixar que ele cuide das atualizações. [more]

Onde eu pego?

O NuGet normalmente vem instalado junto com o ASP.NET MVC mas, caso você não o tenha, pode ir direto na página dele na Visual Studio Galery e clicar em download.

Como eu instalo uma biblioteca pelo NuGet?

  1. No Visual Studio, vá na Solution Explorer e clique com o botão direito em References e selecione Manage NuGet Packages
  2. Quando a janela do NuGet se abrir você pode notar 4 items a esquerda:
    1. Installed packages: Mostra a lista dos pacotes (bibliotecas) já instalados;
    2. Online: Mostra todos os pacotes disponíveis na internet;
    3. Updates: Mostra os updates para os pacotes que você tem;
    4. Recent packages: Mostra a lista de pacotes que você usou recentemente nos seus projetos
  3. Selecione o item Online (normalmente pré-selecionado) e use o campo de busca a direita (Search Online) para procurar o pacote desejado. No nosso caso, digite Json.NET e espere. Os resultados aparecem em alguns segundos (dependendo da sua conexão)
  4. Clique em Install no primeiro item. O NuGet vai fazer o download automaticamente do pacote e instalar no teu projeto
  5. Depois de terminado você pode fechar a janela do NuGet. Note que, além da referência ao Json.NET (Newtonsoft.Json) ter sido adicionada, um arquivo chamado packages.config foi criado na raiz do projeto
  6. Esse arquivo contém os nomes e versões de todos os pacotes do NuGet que foram adicionados ao projeto. Eu recomendaria não enconstar nele :)

Existe também um jeito de instalar via linha de comando. Pra isso basta ir no menu View -> Other Windows -> Package Manager Console. Assim que a janelinha aparecer basta digitar o comando que está escrito na página do projeto que você quer instalar. No caso do Json.NET o comando é Install-Package Newtonsoft.Json.

Eu sinceramente prefiro instalar os pacotes de maneira mais visual. Pode parecer meio burocrático a primeira vista mas nada compensa mais do que ter tudo centralizado na IDE a apenas alguns cliques de distância. Fora que não preciso abrir o site pra isso. Mas, obviamente, cada caso é um caso.

Did you like the article?

You can subscribe and get them as soon they are online, share using the buttons bellow or leave a comment.

And you also can share using your favorite social network: