Arquivos do Blog

Como Formatar Datas com string.Format no C#

Este exemplo abaixo, mostra como podemos formatar um objeto de data DateTime em diversos formatos usando o String.Format.

Quando trabalhamos com data, às vezes é necessário o uso de formatos de data customizados, como por exemplo, uma data no formato mm/yyyy de uma fatura, uma data de um chamado aberto sem os segundos, ou ainda uma data por extenso para o rodapé de um relatório.

Para criar os formatos de data customizados, usamos algumas letras específicas onde cada letra significa uma parte da data. y (ano), M (mês), d (dia), h (hora 12), H (hora 24), m (minuto), s (segundo), f (fração de segundo), F (fração de segundo, mostrando zeros após a unidade inteira ex: 0.2000), t (P.M ou A.M) e z (time zone).

// Criando uma data 09/03/2008 16:05:07.123
DateTime dt = new DateTime(2008, 3, 9, 16, 5, 7, 123);

String.Format("{0:y yy yyy yyyy}", dt);  // "8 08 008 2008"    ano
String.Format("{0:M MM MMM MMMM}", dt);  // "3 03 Mar Março"   mês
String.Format("{0:d dd ddd dddd}", dt);  // "9 09 Dom Domingo" dia
String.Format("{0:h hh H HH}",     dt);  // "4 04 16 16"       hora 12/24
String.Format("{0:m mm}",          dt);  // "5 05"             minuto
String.Format("{0:s ss}",          dt);  // "7 07"             segundo
String.Format("{0:f ff fff ffff}", dt);  // "1 12 123 1230"    fração de segundo
String.Format("{0:F FF FFF FFFF}", dt);  // "1 12 123 123"     fração de segundo sem zero
String.Format("{0:t tt}",          dt);  // "P PM"             A.M. ou P.M.
String.Format("{0:z zz zzz}",      dt);  // "-6 -06 -06:00"    time zone

Quando usamos o separados de data “/” e o separador de tempo “:” eles serão substituídos pelo separador de data e de tempo definidos na cultura atual com o DateTimeForma­tInfo.DateSepa­rator e o DateTimeForma­tInfo.TimeSepa­rator.

// a cultura alemã substitui o separador de data "/" pelo "."
String.Format("{0:d/M/yyyy HH:mm:ss}", dt); // "9/3/2008 16:05:07" - Português Brasileiro (pt-BR)
String.Format("{0:d/M/yyyy HH:mm:ss}", dt); // "9.3.2008 16:05:07" - Alemã (de-DE)

AuthorizationAttribute Customizado no ASP.NET MVC

Vou mostrar um exemplo prático de como podemos criar um AuthorizationAttribute customizado para, por exemplo, redirecionar para uma página específica em caso de acesso não autorizado.

using System.Web.Mvc;
using System.Web.Routing;

namespace MvcApplication1.FilterAttributes
{
    public class MyAuthorizationAttribute : ActionFilterAttribute
    {
        private string _userName;

        public MyAuthorizationAttribute(string userName)
        {
            _userName = userName;
        }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);

            if (!UserIsAuthenticated())
            {
                // Redirect to login page
                filterContext.Result = new RedirectToRouteResult(
                    new RouteValueDictionary
                    {
                        { "controller", "Login" },
                        { "action", "NaoPermitido" }
                    });
            }
        }

        private bool UserIsAuthenticated()
        {
            return HttpContext.Current.User.Identity.Name == _userName;
        }
    }
}

Para usar fazemos assim:

[MyAuthorization("Pedro")]
public ActionResult Teste() ...

Se o nome do usuário logado não for Pedro, será redirecionado para o controller Login e a action NaoPermitido.

Sum com Linq e valores Nullable

Vamos imaginar a seguinte situação.

Temos uma lista de produtos com nome e valor, o valor do produto pode ser nulo:

public class Produto {
	public string Nome { get; set; }
	public decimal? Valor { get; set; }
}

vamos agora tentar obter o valor total dos produtos:

List lista = db.GetProdutos();
decimal soma = lista.Sum(c => c.Valor);

Ao rodar o código, se houver um produto com valor nulo, tomamos um erro.
The cast to value type ‘Decimal’ failed because the materialized value is null. Either the result type’s generic parameter or the query must use a nullable type.
Como resolver este problema?
Para resolver é bem simples, precisamos apenas usar um comando muito útil no C# e que pouca gente conhece, o Null Coalescing (??):

decimal soma = lista.Sum(c => c.Valor ?? 0);

ou com Linq:

decimal soma = (from p in lista
              select p.Valor ?? 0).Sum();

No exemplo acima, com o ?? estou dizendo que é para retornar o Valor diferente de nulo ou 0, Semelhante ao If abaixo:
(p.Valor != null) : p.Valor ? 0

Segue abaixo um código completo mostrando o funcionamento da dica, basta criar um novo projeto Console Application e inserir o código abaixo:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    public class Produto
    {
        public string Nome { get; set; }
        public decimal? Valor { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            List<Produto> lista = new List<Produto>();
            lista.Add(new Produto
            {
                Nome = "Teste 1",
                Valor = (decimal)54.2
            });
            lista.Add(new Produto
            {
                Nome = "Teste 2",
                Valor = null
            });
            lista.Add(new Produto
            {
                Nome = "Teste 3",
                Valor = 65
            });

            decimal soma = (from p in lista
                            select p.Valor ?? 0).Sum();

            Console.WriteLine(soma);
            Console.ReadKey();
        }
    }
}

Passei no Exame 70-513 – WCF

Ontem dia 05/01/2012 fiz a prova da certificação 70-513 “Windows Communication Foundation Development with Microsoft .NET Framework 4″ e passei.

Eu achei a prova com um nível de dificuldade moderado, com muitas questões óbvias que sabendo o mínimo daquele tema dava pra responder tranquilamente.

Essa é minha terceira certificação MCTS no .Net Framework 4 e com ela, estou apto a fazer a prova 70-519 para me tornar MCPD.

Eu utilizei como material de estudo o livro “Windows Communication Foundation 4 Step by Step”, recomendo ele para quem deseja fazer a prova

Como Enviar Email Usando C#

Vou mostrar de maneira simples como podemos enviar email no C# através da classe MailMessage que está no namespace System.Net.Mail.


System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage();
message.To.Add("destinatario@email.com");
message.Subject = "Assunto do email";
message.From = new System.Net.Mail.MailAddress("remetente@email.com");
message.Body = "Corpo da mensagem";
System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient("servidor smtp");
smtp.Send(message);

Lista de destinatários da mensagem:

message.To.Add("destinatario@email.com");

Assunto

message.Subject = "Assunto do email";

Remetente, usamos o objeto MailAddress

message.From = new System.Net.Mail.MailAddress("remetente@email.com");

Corpo da mensagem, é o conteúdo do email

message.Body = "Corpo da mensagem";

Criamos uma instância do objeto SmtpClient que será o objeto responsável por enviar a mensagem, através do método Send()

System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient("servidor smtp");
smtp.Send(message);

Interface IDisposable e o Garbage Collector

O principal uso da interface IDisposable é quando queremos liberar recursos não gerenciados. O Garbage Collector (Coletor de Lixo) automaticamente libera a memória alocada para um objeto gerenciado quando este objeto não está mais em uso. No entanto, não há como prever quando o Garbage Collector irá realizar a coleta do lixo. Além disso, o Garbage Collector não tem conhecimento de recursos não gerenciados, como identificadores de janela, ou recursos externos de manipulação de arquivos.
Com o uso do método Dispose() da interface IDisposable, podemos explicitamente liberar os recursos não gerenciados em conjunto com o Garbage Collector.

using System;
using System.IO;

//Implementação da interface IDisposable
public class MyReader : IDisposable
{
    //Um StreamReader, que apesar de trabalhar com
    //recursos nao gerenciados, é um objeto do
    //.Net framework e já tem implementada a interface
    //IDisposable e é tratado como um objeto gerenciado
    StreamReader reader;
    bool disposed = false;

    //Inicializa o reader
    public MyReader(string file)
    {
        reader = new StreamReader(file);
    }
    //Utiliza recursos do reader normalmente

    public string ReadToEnd()
    {
        return reader.ReadToEnd();
    }

    //Finalizador:
    //Este metodo é o finalizador, que é invocado pelo GC
    //para liberar os recursos.
    //Toda a liberação implementada dentro dele só será
    //executada quando o método for invocado, porém não
    //conseguimos saber quando isto vai acontecer e recursos
    //importantes podem ficar presos até que isto aconteça.
    ~MyReader()
    {
        Dispose(false);
    }

    //Quando o Dispose é acionado, os recursos gerenciados e
    //não gerenciados são liberados e ainda avisamos o GC
    //para nao acionar o finalizador pois ele já não é mais necessário
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    private void Dispose(bool disposing)
    {
        //Caso o objeto ainda não tenha sido destruído
        //libera-se os recursos
        if (!this.disposed)
        {
            //Se o objeto estiver sendo destruído através do metodo
            //Dispose libera-se os recurso gerenciados

            if (disposing)
            {
                //Libera recursos gerenciados
                reader.Dispose();
            }
            //Sempre libera-se os recursos não gerenciados, como utilização de ponteiros
            //em chamadas a API do Windows e já assume-se que os recursos foram liberados
            disposed = true;
        }
    }
}

O que é o Domínio de Aplicativo (Application Domain)?

Na Common Language Runtime (CLR), um Domínio de Aplicativo é um mecanismo (similar a um processo em um sistema operacional) usado para isolar aplicações em execução uma das outras para que elas não afetem umas as outras.

O domínio de aplicativo da Common Language Runtime está contido dentro de um processo do sistema operacional. Um processo pode conter muitos domínios de aplicativo.

Domínios de aplicativo têm propriedades de isolamento semelhantes as de processos do sistema operacional:

  • Múltiplas threads podem existir dentro de um único domínio de aplicativo.
  • Um aplicativo em um domínio pode ser interrompida sem afetar o estado de outro domínio no mesmo processo.
  • Uma falha ou exceção em um domínio não afetam um aplicativo em outro domínio.
  • Informações de configuração faz parte do escopo de um domínio, e não do escopo do processo.
  • Para cada domínio podem ser atribuído diferentes níveis de acesso de segurança.
  • O código em um domínio não pode acessar diretamente o código em outro.
  • Neste sentido, o CLR é como um mini sistema operacional. Roda um único processo que contém vários sub-processos, ou domínios de aplicativo.
  • A vantagem de domínios de aplicativo é que a execução de vários domínios de aplicativo requer menos recursos, como memória, do que a execução de processos de múltiplos sistemas operacionais.
Domínio de aplicativo também podem ser explicitamente criados por aplicativos .NET. Aqui abaixo está um exemplo em C# que cria um domínio de aplicativo (AppDomain), cria uma instância de um objeto dentro dele, e então executa um dos métodos do objeto. Note que você deve nomear o executável para ‘appdomaintest.exe ‘ para funcionar corretamente.
using System;
using System.Runtime.Remoting;
public class CAppDomainInfo : MarshalByRefObject
{
	public string GetAppDomainInfo()
	{
		return "AppDomain = " + AppDomain.CurrentDomain.FriendlyName;
	}
}

public class App
{
	public static int Main()
	{
		AppDomain ad = AppDomain.CreateDomain( "Andy's new domain", null, null );
		ObjectHandle oh = ad.CreateInstance( "appdomaintest", "CAppDomainInfo" );
		CAppDomainInfo adInfo = (CAppDomainInfo)(oh.Unwrap());
		string info = adInfo.GetAppDomainInfo();
		Console.WriteLine( "AppDomain info: " + info );
		return 0;
	}
}
Seguir

Obtenha todo post novo entregue na sua caixa de entrada.

%d bloggers like this: