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 C#, Tutoriais, 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 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 C#, Dicas, Tutoriais, 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:

Redimensione imagens dinamicamente em C# mantendo sua proporção

Veja como é fácil redimensionar imagens usando C# e, o mais importante: Proporcionalmente!

Posted in C#, Dicas

Existem alguns momentos que, enquanto desenvolvendo um projeto, temos que parar de fazer o que estamos acostumados (brincar com classes e acesso a banco) para que possamos fazer algo que nunca fizemos ou que não fazemos com frequência. No meu caso é edição de imagens.

O código abaixo é muito simples os poucos comentários que tem (em inglês) podem te dar uma idéia do que está acontecendo. De qualquer modo, o único trabalho que você vai ter vai ser copiar o código e colar no seu projeto. Daí você só vai precisar de fazer a chamada de maneira correta e, voilà! Imagem redimensionada proporcionalmente!!

 

public static void ResizeImage(string originalFile, string newFile, int newWidth, int maxHeight, bool onlyResizeIfWider)
{
	Image fullsizeImage = Image.FromFile(originalFile);
 
	// Prevent using images internal thumbnail
	fullsizeImage.RotateFlip(RotateFlipType.Rotate180FlipNone);
	fullsizeImage.RotateFlip(RotateFlipType.Rotate180FlipNone);
 
	if (onlyResizeIfWider)
	{
		if (fullsizeImage.Width <= newWidth)
		{
			newWidth = fullsizeImage.Width;
		}
	}
 
	int newHeight = fullsizeImage.Height * newWidth / fullsizeImage.Width;
	if (newHeight > maxHeight)
	{
		// Resize with height instead
		newWidth = fullsizeImage.Width * maxHeight / fullsizeImage.Height;
		newHeight = maxHeight;
	}
 
	Image newImage = fullsizeImage.GetThumbnailImage(newWidth, newHeight, nullIntPtr.Zero);
 
	// Clear handle to original file so that we can overwrite it if necessary
	fullsizeImage.Dispose();
 
	// Save resized picture
	newImage.Save(newFile);
}

Só lembre-se de salvar as imagens em uma pasta com as permissões de leitura e escrita para evitar erros.

via DZone snippets

		public static void ResizeImage(string originalFile, string newFile, int newWidth, int maxHeight, bool onlyResizeIfWider)
		{
			Image fullsizeImage = Image.FromFile(originalFile);
 
			// Prevent using images internal thumbnail
			fullsizeImage.RotateFlip(RotateFlipType.Rotate180FlipNone);
			fullsizeImage.RotateFlip(RotateFlipType.Rotate180FlipNone);
 
			if (onlyResizeIfWider)
			{
				if (fullsizeImage.Width <= newWidth)
				{
					newWidth = fullsizeImage.Width;
				}
			}
 
			int newHeight = fullsizeImage.Height * newWidth / fullsizeImage.Width;
			if (newHeight > maxHeight)
			{
				// Resize with height instead
				newWidth = fullsizeImage.Width * maxHeight / fullsizeImage.Height;
				newHeight = maxHeight;
			}
 
			Image newImage = fullsizeImage.GetThumbnailImage(newWidth, newHeight, nullIntPtr.Zero);
 
			// Clear handle to original file so that we can overwrite it if necessary
			fullsizeImage.Dispose();
 
			// Save resized picture
			newImage.Save(newFile);
		}

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 criar uma lista de fuso horários em C#

Veja como é fácil criar uma lista de fuso horários!

Posted in C#, Dicas

Suponhamos que você está desenvolvendo um sistema que requer que o usuário tenha que escolher qual o fuso horário em que ele está. Agora imagine que você tenha que adicionar 40 fusos em um dropdownlist manualmente.

A não ser que você precise de ter uma lista de fusos dentro do banco de dados você pode usar o seguinte código:

public static IEnumerable<SelectListItem> TimeZoneCollection
{
	get
	{
		return new SelectList(TimeZoneInfo.GetSystemTimeZones()
			.Select(q => new SelectListItem
						{
							Text = q.DisplayName,
							Value = (q.DisplayName.Substring(0, 5) != "(UTC)") ? q.DisplayName.Substring(4, 3) : "0"
						}
 
				    ), "Value""Text");
	}
}

Agora é só dar bind no dropdownlist e voilà.

P.S.: Caso você melhore o código me avise. :)

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: