// Rodolfo Fadino

/* LIFE RUNS ON CODE */

Archive for the ‘C#’ Category

A Amazon Web Service  oferece diversos produtos e soluções em cloud computing, atualmente ela forneçe uma das mais completas gama de produtos e soluções do mercado de cloud. Uma dessas soluções é o Amazon Simple Storage Service (Amazon S3), que consiste em uma plataforma de armazenamento, onde é possível criar diversos containers e gerenciar arquivos, permissões, etc.

Durante esta semana estava estudando alguns serviços para um backup off-site, entre todos eles eu optei por utilizar o S3, a partir desta escolha comecei a estudar com quais ferramentas eu poderia automatizar a tranferência entre meus servidores e o armazenamento na S3. No mercado exitem diversas ferramentas para isso, entre elas optei por utilizar o SDK da Amazon e PowerShell, no qual eu consegui escrever a rotina que eu precisava e configurar esse script como uma tarefa agendada do windows server.

Começando

Para começar vamos precisar fazer donwload do SDK da Amazon para .NET, eu poderia ter feito um programa com C# utilizando o SDK da Amazon, mas como a idéia é utilizar e aprender a usar PowerShell, utilizei ele para escrever um script que copia todos os arquivos de um diretorio para a S3.

Inicialmente eu utilizei um método de upload ( .Upload ) do SDK que funcionava bem para arquivos pequenos, entretanto, como a idéia era fazer backup de grandes arquivos (+de 1G) eu precisei utilizar uma feature da API da Amazon chamada Multipart Upload (Using the AWS SDK for .NET for Multipart Upload) nela, eu particiono o arquivo, faço upload de todas as partes, e, no final do upload eu utilizo um comando que une todas as partes, criando a versão final do arquivo.

Para iniciar o script vou incluir a dll do SDK da Amazon:

Add-Type -Path "C:\Program Files (x86)\AWS SDK for .NET\bin\AWSSDK.dll"

Como segundo passo do meu script adicionarei as variáveis de acesso da API (com um usuário que eu criei e gerei a chave de acesso) e também criarei a variável com o Bucket que eu criei na S3

$secretKeyID="colocar secret key"
$secretAccessKeyID="colocar access key"
$bucket="NomeDoBucket"

O proximo passo do script é definir qual diretório eu farei o backup (“C:\teste”) e qual será o nome do diretório final no Bucket da S3 (“Backup_yyyy_mm_dd”):

$backup_directory="C:\teste"
$new_folder_format = Get-Date -uformat "Backup_%Y_%m_%d/"

Agora eu criarei um laço entre todos os arquivos do diretório, dentro desse laço nos faremos todo o trabalho de upload dos arquivos:

foreach($file in Get-ChildItem -Path $backup_directory){

#script de upload

}
Write-Host "Backup Finalizado"

Dentro desse laço, para cada arquivo eu farei o seguinte:

Escrever o nome do arquivo e instanciar o Cliente de acesso para a AWS

Write-Host $file.fullname
$client=[Amazon.AWSClientFactory]::CreateAmazonS3Client($secretKeyID,$secretAccessKeyID)

Em um segundo passo eu defino os nomes do arquivo final e o nome do arquivo fisico para fazer o upload.

$finalName=$new_folder_format+$file.name
$fileFullPath=$file.fullname

Também instancio um List de UploadPartResponse e uma instancia do InitiateMultipartUploadRequest para iniciarmos o upload.

$uploadResponses = New-Object "System.Collections.Generic.List[Amazon.S3.Model.UploadPartResponse]"

$initRequest=New-Object "Amazon.S3.Model.InitiateMultipartUploadRequest"
[void] $initRequest.WithBucketName($bucket)
[void] $initRequest.WithKey($finalName)

Com isso já podemos iniciar o MultipartUpload com o $client passando o $initRequest, tambem instancio algumas variaveis de controle, que utilizaremos para fazer upload de 5Mb por parte do arquivo.

$initResponse =$client.InitiateMultipartUpload($initRequest)

$fileInfo = New-Object -TypeName System.IO.FileInfo $arquivoFisico
$lengh= $fileInfo.Length
$partSize= 5242880

$filePosition =New-Object "Long"
$filePosition = 0

Com essas variaveis eu faço um loop entre as partes do arquivo para fazer upload de cada 5Mb

for ( $partNumber = 1; $filePosition -le $lengh;  $partNumber++)
{
	$uploadRequest = New-Object "Amazon.S3.Model.UploadPartRequest"
	[void] $uploadRequest.WithBucketName($bucket)
	[void] $uploadRequest.WithKey($finalName)
	[void] $uploadRequest.WithUploadId($initResponse.UploadId)
	[void] $uploadRequest.WithPartNumber($partNumber)
	[void] $uploadRequest.WithPartSize($partSize)
	[void] $uploadRequest.WithFilePosition($filePosition)
	[void] $uploadRequest.WithFilePath($fileFullPath)

	$uploadResponses.Add($client.UploadPart($uploadRequest))
	$filePosition += $partSize
	Write-Host $partNumber
}

Finalmente podemos juntar todas as partes do upload, para isso utilizamos o seguinte comando:

$compRequest = New-Object "Amazon.S3.Model.CompleteMultipartUploadRequest"
[void] $compRequest.WithBucketName($bucket)
[void] $compRequest.WithKey($finalName)
[void] $compRequest.WithUploadId($initResponse.UploadId)
[void] $compRequest.WithPartETags($uploadResponses)

$completeUploadResponse =$client.CompleteMultipartUpload($compRequest)

Por ultimo precisamos fechar o laço que fizemos entre cada arquivo do diretorio e escrevo uma mensagem de finalizado, com isso o script ficou da seguinte maneira:

Add-Type -Path "C:\Program Files (x86)\AWS SDK for .NET\bin\AWSSDK.dll"

$secretKeyID="secret key"
$secretAccessKeyID="access key"
$bucket="BucketName"

$backup_directory="C:\teste"
$new_folder_format = Get-Date -uformat "Backup_%Y_%m_%d/"

foreach($file in Get-ChildItem -Path $backup_directory){
	Write-Host $file.fullname
	$client=[Amazon.AWSClientFactory]::CreateAmazonS3Client($secretKeyID,$secretAccessKeyID)

	$finalName=$new_folder_format+$file.name
	$fileFullPath=$file.fullname

	$uploadResponses = New-Object "System.Collections.Generic.List[Amazon.S3.Model.UploadPartResponse]"

	$initRequest=New-Object "Amazon.S3.Model.InitiateMultipartUploadRequest"
	[void] $initRequest.WithBucketName($bucket)
	[void] $initRequest.WithKey($finalName)

	$initResponse =$client.InitiateMultipartUpload($initRequest)

	$fileInfo = New-Object -TypeName System.IO.FileInfo $fileFullPath
	$lengh= $fileInfo.Length
	$partSize= 5242880

	$filePosition =New-Object "Long"
	$filePosition = 0

	for ( $partNumber = 1; $filePosition -le $lengh;  $partNumber++)
	{
		$uploadRequest = New-Object "Amazon.S3.Model.UploadPartRequest"
		[void] $uploadRequest.WithBucketName($bucket)
		[void] $uploadRequest.WithKey($finalName)
		[void] $uploadRequest.WithUploadId($initResponse.UploadId)
		[void] $uploadRequest.WithPartNumber($partNumber)
		[void] $uploadRequest.WithPartSize($partSize)
		[void] $uploadRequest.WithFilePosition($filePosition)
		[void] $uploadRequest.WithFilePath($fileFullPath)

		$uploadResponses.Add($client.UploadPart($uploadRequest))
		$filePosition += $partSize
		Write-Host $partNumber
	}

	$compRequest = New-Object "Amazon.S3.Model.CompleteMultipartUploadRequest"
	[void] $compRequest.WithBucketName($bucket)
	[void] $compRequest.WithKey($finalName)
	[void] $compRequest.WithUploadId($initResponse.UploadId)
	[void] $compRequest.WithPartETags($uploadResponses)

	$completeUploadResponse =$client.CompleteMultipartUpload($compRequest)
}
Write-Host "Backup Finalizado"

O  script também pode ser encontrado no meu GitHub: https://gist.github.com/2691325

Para executar o script eu criei uma tarefa agendada, para isso eu coloquei o seguinte comando:

Caso o script apresente erro de segurança ao executar, é necessário habilitar a execução de scripts na maquina, abra um prompt do PowerShell e utilize o seguinte comando:

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned

Espero que este post seja útil,

estou a disposição para dúvidas, críticas e sugestões.

abs

Rodolfo

C# , dev , Server

Um dos melhores formatos para transmitir dados na web é o Json (JavaScript Object Notation),  já que é nativo do JavaScript e possui menor overhead de separadores que em um XML por exemplo, alem disso, é facilmente tratado por funções JS.

Cada vez mais a maioria de projetos utiliza JSON em suas API’s, integrações ou em outras comunicações.

A idéia deste post é demonstrar algumas facilidades e maneiras de trabalhar com JSON utilizando dynamic e C#.

Para isso precisaremos instalar e referenciar a namespace do System.Json, que pode ser incluida através de Nuget:

(Install-Package System.Json)

 

Criando JSON

Com o dynamic (http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.aspx) é possivel extender a classe JsonObject (http://msdn.microsoft.com/en-us/library/system.json.jsonobject(v=vs.110).aspx) para criarmos com muita facilidade nosso objetos JSON.

Ex:

dynamic usuario = new JsonObject();
usuario.nome = "Rodolfo";
usuario.sexo = "m";
usuario.idade = 22;

dynamic certificacoes = new JsonArray();

dynamic certificacao1 = new JsonObject();
certificacao1.titulo = "MCPD";
certificacao1.id = 1;

dynamic certificacao2 = new JsonObject();
certificacao2.titulo = "MCTS";
certificacao2.id = 2;

dynamic certificacao3 = new JsonObject();
certificacao3.titulo = "MCP";
certificacao3.id = 3;

certificacoes.Add(certificacao1);
certificacoes.Add(certificacao2);
certificacoes.Add(certificacao3);

usuario.certificacoes = certificacoes;

Console.WriteLine(usuario.ToString());

Terá criado a seguinte string

{"nome":"Rodolfo","sexo":"m","idade":22,"certificacoes":
[{"titulo":"MCPD","id":1},{"titulo":"MCTS","id":2},{"titulo":"MCP","id":3}]}

 

Lendo strings com JSON

Outra função fundamental é converter strings de JSON em objetos que podem ser trabalhados, para isso, neste exemplo eu utilizarei o dynamic e o JsonValue (http://msdn.microsoft.com/en-us/library/system.json.jsonvalue(v=vs.110).aspx)

Ex:

var jsonString = "{\"nome\":\"Rodolfo Fadino\",\"idade\":22, \"sexo\":\"M\"}";
dynamic jsonTratado = JsonValue.Parse(jsonString);

string Nome = jsonTratado.nome;
char Sexo = jsonTratado.sexo;
int idade = jsonTratado.idade;

 

Abaixo seguem os link’s da MSDN

http://msdn.microsoft.com/en-us/library/system.json(v=vs.110).aspx

http://msdn.microsoft.com/en-us/library/system.dynamic.aspx

 

Bom espero que este post tenha sido util,

estou a disposição para dúvidas, críticas e sugestões

 

abs

Rodolfo

C#

Fiz um post a um tempo atras (http://www.rodolfofadino.com.br/2011/12/facebook-sdk-para-asp-net-mvc/), que utilizava o SDK para Facebook em C#, este projeto sofreu algumas reestruturações , algumas namespaces e funcionalidades foram removidas.

Atualmente ele está uma versão bem estável, sendo hospedado no GitHub.

Abaixo seguem os links novos do SDK:

http://csharpsdk.org

https://github.com/facebook-csharp-sdk

abs

Rodolfo

C#

No cenário atual de envio de -emails (milhões de spam’s, vendas de bases, optouts que não são respeitados) garantir a entrega de um e-mail para o usuário é uma missão diária e requer várias técnicas, desde formatação e contrução do html, encoding, configurações de DNS, SPF, Dkin, etc.

O .NET Framework dispõe de diversas features para trabalharmos com e-mails, podemos configurar headers, portas, criptografia, autenticação, etc.

Enviar um e-mail com versões em texto plano e html é uma técnica que melhora o recebimento e a leitura de um e-mail nos diversos dispositivos pelo usuário.

A classe MailMessage fornece uma propriedade chamada AlternateViews na qual é possível adicionar várias Views para o mesmo e-mail, com isso nos podemos adicionar no mesmo e-mail várias visualizações: texto plano, html, etc.

Abaixo segue um exemplo de como utilizar:

MailMessage mailMsg = new MailMessage();

// To
mailMsg.To.Add(new MailAddress("to@example.com", "To Name"));
// From
mailMsg.From = new MailAddress("from@example.com", "From Name");
// Subject
mailMsg.Subject = "subject";

//Texto
string text = "text body";
//Html
string html = @"<p>html body</p>";

//Views Texto e Html
mailMsg.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(text, null, MediaTypeNames.Text.Plain));
mailMsg.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(html, null, MediaTypeNames.Text.Html));

//Send
SmtpClient smtpClient = new SmtpClient();
smtpClient.Send(mailMsg);

No detalhe:

//View Texto
mailMsg.AlternateViews.Add(
    AlternateView.CreateAlternateViewFromString
    (text, null, MediaTypeNames.Text.Plain));
//View Html
mailMsg.AlternateViews.Add(
    AlternateView.CreateAlternateViewFromString
    (html, null, MediaTypeNames.Text.Html));

Espero que este post seja útil,

estou a disposição para dúvidas, criticas e sugestões

abs :)

Rodolfo

C#

O operador ?: pode ser ilustrado da seguinte maneira

condicao ? primeira_expressao : segunda_expressao;

A condição é avaliada como Verdadeira ou Falsa, no caso da condição ser Verdadeira a primeira_expressao é avaliada e será retornada, no caso da condição ser Falsa a segunda_expressao é avaliada e será retornada como resultado.

A documentação é clara quando as necessidade das duas expressões retornarem o mesmo tipo. Mesmo que para isso seja necessário uma conversão explicita.

Algumas vezes em situações precisamos utilizar este operador com tipos que podem ser nulos. Como o exemplo abaixo:

Pessoa pessoa = new Pessoa();
int? codigo = (pessoa==null) ? null : pessoa.Id;

Nesse exemplo temos um objeto pessoa, que pode ser nulo ou não, se ele for nulo, temos que atribuir null a variável codigo, se não atribuiremos o Id (int) do objeto pessoa.

Este exemplo apresenta o seguinte erro durante a compilação

Type of conditional expression cannot be determined because there 
is no implicit conversion between '<null>' and 'int'

Uma das maneiras de corrigir este código é convertendo o null para int?, o que pode ser feito da seguinte maneira:

Pessoa pessoa = new Pessoa();
int? codigo = (pessoa == null) ? (int?)null : pessoa.Id;

Ou convertendo o Id da pessoa para int?, o que importa é que eles retornem explicitamente um tipo nullable:

Pessoa pessoa = new Pessoa();
int? codigo = (pessoa == null) ? null : (int?)pessoa.Id;

espero que esta dica rápida seja útil.

abs

Rodolfo

C#

Série de artigos muito legais de James Michael Hare, com muitas dicas e técnicas que melhoram consideravelmente a maneira que programamos.

C#/.NET Five Little Wonders That Make Code Better (1 of 3)

1.  The Null Coalescing Operator (??)
2.  The As Cast
3.  Auto-Properties
4.  The Stopwatch Class
5.  TimeSpan factory methods

Link: http://geekswithblogs.net/BlackRabbitCoder/archive/2010/08/26/c.net-five-little-wonders-that-make-code-better-1-of.aspx

C#/.NET Five More Little Wonders That Make Code Better (2 of 3)

1. string.IsNullOrEmpty() and string.IsNullOrWhiteSpace()
2. string.Equals()
3. using Statements
4. static Class Modifier
5. Object and Collection Initializers

Link: http://geekswithblogs.net/BlackRabbitCoder/archive/2010/09/02/c.net-five-more-little-wonders-that-make-code-better-2.aspx

C#/.NET Five More Little Wonders That Make Code Better (3 of 3)

1. Implicit Typing
2. LINQ Extension Methods
3. Extension Methods
4. System.IO.Path
5. Generic Delegates

Link: http://geekswithblogs.net/BlackRabbitCoder/archive/2010/09/09/c.net-five-final-little-wonders-that-make-code-better-3.aspx

Vale o estudo.

Rodolfo

C#