Skip to main content

Criando páginas de erro 404 personalizadas no ASP.NET MVC

É muito fácil de se criar páginas de erro personalizadas no MVC. Veja como fazer.

Posted in ASP.NET, Dicas, MVC

Todo mundo que trabalha fazendo sites sabe que ter páginas de erro é indispensável. Só que quando se trabalha com ASP.NET MVC é muito complicado se acertar na hora de configurar as páginas de erro. Sim, usar o web.config é o recomendado. Mas você tem certeza de que está funcionando?

Objetivo

O nosso objetivo aqui é aprender a fazer uma página personalizada de erro 404 e retornar o HTTP status code correspondente (404) sem alterar a url.

O que aprendemos sobre erros no começo

Normalmente, quando estamos iniciando no ASP.NET, aprendemos que temos que colocar a tag no web.config, configurar os parâmetros e esperar o erro aparecer. Veja o exemplo abaixo:

<customErrors mode="On">
	<error statusCode="404" path="erro404.html" />
customErrors>

Páginas 404 personalizadas

Normalmente quando uma página não existe o site retorna o erro 404, não importa se a página é estática (página html simples) ou dinâmica (página gerada pelo backend). No caso do exemplo acima o ASP.NET a gente está dizendo para o site para redirecionar para uma página amigável quando acontecer algum erro 404.

Até aí tudo bem.

O problema do MVC

No caso do MVC o buraco acaba sendo mais embaixo: Como o MVC é baseado em routes, controles e actions uma url como /lala/lele não vai passar pelo . O resultado vai ser aquele erro 404 padrão do ASP.NET.

A solução pra esse problema é simples, mas não é a mais correta. Basta colocar um redirect=”~/ erro404.html” no lugar do path, como no exemplo abaixo:

<customErrors mode="On">
	<error statusCode="404" redirect="~/erro404.html"/>
customErrors>

Agora, se você navegar pra uma url aleatória (lala/lele) você vai ser capaz de ver a sua página personalizada de erro. Só que, além da url se tornar /erro404.html?aspxerrorpath=/lala/lele você vai ver que o HTTP status code da página é 200.

E isso é muito longe do objetivo que traçamos no começo.

Não sou especialista em SEO mas deixa eu tentar explicar o problema: Se por um acaso a página que os indexadores acharem não existe, mas estamos retornando 200, eles vão achar que a página existe e vão indexar a página 404 personalizada como se ela fizesse parte da navegação do site.

A solução ideal

Como eu disse no começo, a ideia é retornar uma página de erro 404 personalizada junto com o HTTP status code correto, que é 404. E obviamente não podemos alterar a url. A maneira mais prática de se fazer isso é mexer direto no IIS. Claro que eu não vou tentar te convencer a ligar no seu host e pedir pra mudar alguma configuração. Para isso vamos usar o .

Simplificando: Enquanto o funciona no mesmo nível do ASP.NET, o funciona mais próximo ao IIS. O que significa que as alterações no vão afetar até mesmo arquivos estáticos. Logo, se quisermos fazer alguma alteração que seja mais próxima do servidor, é lá que devemos mexer.

Para fazer com que nossa página de erro 404 personalizada funcione no MVC devemos fazer como no exemplo a seguir:

<httpErrors errorMode="Custom">
	<remove statusCode="404"/>
	<error statusCode="404" path="/erro404.html" responseMode="File"/>
httpErrors>

Reparou que eu usei um antes? Isso evita erros caso já tenha algum statusCode=”404” definido. E, apesar de eu estar usando uma página html simples (o ideal), podemos usar uma rota específica para a página 404. Como por exemplo /erro/404. Só que nesse caso é recomendado usar o responseMode=”ExecuteUrl”.

Agora, se formos acessar uma url aleatória /lala/lele vamos ver que:

  1. A página 404 foi chamada
  2. O HTTP status code é 404
  3. A url não foi alterada

Pronto. Espero que isso tenha sanado suas dúvidas. De qualquer forma fique à vontade para comentar e perguntar.

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 fazer com que a sessão não expire usando Forms Authentication

Uma dica rápida de como fazer com que a sessão só expire depois de 1 ano

Posted in ASP.NET, Dicas

Tem dias que a gente tem que voltar ao básico pra resolver um problema. E hoje foi um desses dias.

Temos um projeto onde usamos Forms Authentication para login. Nada muito complexo: É um sistema de avaliação com algumas perguntas de multipla escolha. Não customizamos o Forms Authentication pois só queríamos um nível básico de autenticação. Só que os usuáros começou a ter problemas e, depois de algum tempo, achamos a solução.

O problema

O usuário logava, trabalhava mas, depois de um tempo, o sistema voltava automaticamente para a tela de login sem salvar as informações.

A solução

No nosso caso, como o sistema é pequeno e só ficava inconveniente para o usuário ter que colocar as respostas novamente, resolvemos o problema colocando a sessão para expirar em 1 ano. Eu sei, é muito. Mas dá pra trabalhar com folga. Eis o código:

<authentication mode="Forms">
	<forms loginUrl="~/" timeout="525949" /> 
<authentication>

Existem, no entanto, outras soluções. Tem uma que chamam de "heartbeat" onde a sessão é atualizada a cada 5 minutos via ajax. Talvez eu faça mini projeto em forma de tutorial e poste aqui qualquer dia desses. ;-)

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:

A importância de selecionar um bom programador .NET

Com um bom programador no time você pode evitar estresse em projetos de qualquer tamanho

Posted in ASP.NET, Dicas, Carreira

Antes de mais nada, contexto: Vou chamar o setor onde trabalho de hub já que todas as tarefas de criação e publicação de sites é centralizada no meu escritório. No caso de publicação nós temos 2 alternativas: Fazemos um teste rápido antes de publicar ou testamos com mais cuidado e fazemos revisão de código antes de mandarmos pra produção. Isso depende do cliente.

Pois bem. Alguns dias atrás recebemos no hub um pedido para publicar um site. Disseram que não precisávamos testar e que era só jogar online. Assim o fiz. O problema é que o site começou a gerar erro de permissão de pasta. Fiz as devidas correções e o problema foi resolvido.

Eu juro que me deu vontade de xingar até a 5ª geração do cara que programou o site. Ele cometeu erros básicos como colocar os arquivos de dados (neste caso XML) fora de App_Data, colocou as tags do XML sem padrão (algumas tinham maiúsculas, outras não) e passou bem longe de reusar o código. Sim, ele criou o mesmo método várias vezes para fazer a mesma coisa. Só que em páginas diferentes.

Para evitar que outras pessoas façam isso eu vou botar 3 dicas rápidas. Guardem no coração de vocês:

  1. Use App_Data para salvar arquivos – Não importa que tipo de arquivos você vai colocar lá dentro, seja XML ou até mesmo um banco de dados SQL. Esta pasta tem nativamente permissões para leitura e escrita. Pode ser que localmente aquela pasta chamada “DB” na raiz do site funcione, mas isso não garante que funcionará em produção. Já App_Data é garantido.
  2. XML é case sensitive – Tem muita gente que não sabe disso porque só usa letras minúsculas quando está criando os nodes no XML. Mas é case sensitive sim, pode fazer o teste.
  3. Reuse seu código – Parece piada mas tem muita gente no mercado que cria aquele método “SalvaArquivo” várias vezes em vários lugares diferentes e, pra piorar, fazendo a mesma coisa. Se o método vai ser usado em vários lugares é bom criar em um lugar centralizado para facilitar a manutenção.

Só frisando: Isso foi em um projeto ASP.NET com Web Forms.

Não sei a história dele ou do projeto. Mas se formos pensar um pouco além do código chegamos a conclusão de que ele foi mal escalado para o projeto pois, saibam vocês, é um site grande de uma marca exposta internacionalmente. Claro que ele deve estar feliz de colocar no currículo que fez um site grande. Só que nós do hub sabemos que o cara é bem mediano e que deve ter achado algum site com dicas de entrevista de emprego pra poder conseguir a vaga. Mas nada que um treinamento e um pouco de dedicação nos estudos não resolvam.

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:

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 ASP.NET, C#, Tutoriais, 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:

Por que escolhi trabalhar com ASP.NET?

Não tem detalhes técnicos da tecnologia e nem comparativos. É mais uma opinião pessoal mesmo.

Posted in ASP.NET, Dicas, Tecnologia, Carreira

Acho que já está mais do que claro que eu sou focado nas tecnologias Microsoft e, sendo mais específico, em ASP.NET. Como muita gente me pergunta porque segui este caminho resolvi criar um artigo contando mais ou menos o que aconteceu para eu chegar no combo ASP.NET / C#. Ah sim, é bom adiantar que não vou entrar em detalhes técnicos neste texto.

Tudo começou lá pelo ano 2000, quando estava terminando o segundo grau técnico. Na época eu estava estudando Delphi e Visual Basic (VB) enquanto era muito curioso com relação a web. Nada de servidores ou rede e sim como as páginas funcionavam. Porém, o que eu sabia de web na época era o básico de HTML, zero de Javascript e menos ainda de CSS. Se falarmos de linguagem de servidor eu citaria o CGI mas só porque um colega de classe enchia o saco falando que ele fez um formulário de contato, formulário de cadastro e por aí vai. Enquanto isso eu tinha um site com 5 páginas no HPG.

Só fui perceber que a web seria algo que teria mercado bem no final do curso. E o caminho natural foi o ASP clássico já que eu sabia VB. Veja bem: Eu gostava mais de Delphi do que de VB. Descontando o fato de ter sido apresentado antes para o ASP do que para o PHP, o que me ajudou nessa migração foi o finado Front Page 2000. Na época bastava ter um banco de dados Access que ele o leria e criaria o formulário para, depois, só precisar de uma customização básica. Algo que o ASP.NET MVC tem hoje e a Microsoft chama de scaffolding.

Daí eu resolvi investir: Comprei um livro de ASP 3 (era esse mesmo do link!!). Apesar de não ter avançado tanto quanto gostaria eu tive uma boa noção de quão ruim era o ASP. E juro que desanimei depois de um tempo. Nem tanto pela qualidade duvidosa do ASP 3 (quem se lembra do erro “Parâmetros insuficientes. Eram esperados 1"?), mas pela péssima qualidade do mercado de desenvolvimento web em Vitória. Naquela época eu me sentia muito confortável por lá. Não me via saindo da casa da minha mãe e indo pra São Paulo, por exemplo. Ou até mesmo pra outro país. E foi justamente nesse período sabático de programação que saiu o .NET Framework.

Já na Polônia, em 2006, eu comecei a me reciclar e percebi que tinha que aprender muito mais do que eu achava que deveria: ASP.NET, AJAX, C#, HTML avançado, CSS e por aí vai.

Não foi fácil.

Só que a partir daí o caminho foi mais natural e a Microsoft ajudou bastante com isso. Para quem não sabe ela facilita muito na hora de se começar a desenvolver um projeto. As opções que o Visual Studio tem para um projeto web, por exemplo, são bem variadas. E boa parte das bibliotecas Javascript necessárias já são copiadas por padrão durante a criação do projeto. Some isso ao fato do Visual Studio ter o Nuget facilitando na hora de adicionar novas bibliotecas.

Sem falar do próprio .NET Framework que já existe em todas as máquinas que rodam Windows.

Em 2012 eu tirei meu MCT e passei 6 meses dando aula em São Paulo. Tive a oportunidade de conhecer gente de vários níveis – básico a avançado – que trabalhavam nas mais variadas tecnologias. Foi ótimo pois me deu uma boa visão de como anda o mercado ASP.NET no Brasil: Paga bem, mas tem que conhecer várias tecnologias diferentes. O mínimo que um programador ASP.NET normalmente tem que saber é: ASP.NET/C#, Web Forms/MVC, Javascript, CSS, SQL Server. Variando de básico pra avançado, além de ter conhecimento teórico e prático.

Enfim... É bom deixar claro que não estou dizendo que ASP.NET é melhor do que o que existe por aí. ASP.NET é melhor pra mim pois ela quem valorizou meu currículo, além de pagar minhas contas no fim do mês.

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 ASP.NET, C#, Dicas, Tutoriais

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: