Arquivo da categoria: .NET

Dicas, exemplos de código, soluções e opniões sobre a plataforma de desenvolvimento da Microsoft

C# – Instanciando uma coleção IQueryable no LINQ

A imagem não tem muito contexto, mas achei ela bonita
Imagem de efeito

Mais uma daquelas que vale pela simplicidade.

Nunca precisei muito fazer questão de instanciar uma coleção usando LINQ e Entity Framework. Normalmente até criava as instâncias sem especificar o tipo, usando var mesmo.

Bem, isso se resolvia quando você não precisa fazer muita coisa com a variável de retorno, ou quando fazia a atribuição direta, vindo da query LINQ. Mas, e quando não dá para fazer a atribuição? Você pergunta, pra quê instanciar? Eu respondo: tem horas que é necessário, por exemplo, quando hoje precisei criar uma coleção em memória sem conectá-la diretamente ao contexto, que seria serializada mais tarde (em JSON). E como a resposta seria para uma aplicacação front-end, null não é a melhor opção.

Como instanciar um IQueryable? Simples:

IQueryable listData = Enumerable.Empty<T>().AsQueryable()

Funcionou perfeitamente! Na serialização, o resultado era uma coleção vazia (“listData”: []).

Simples e economizou um buzilhão de ifs, new List e muitos níveis de complexidade ciclomática.

Fonte: http://stackoverflow.com/a/29430798/1209721

Bom proveito!

C# – Embutindo um servidor HTTP na sua aplicação

httpserver

A pressão faz diamantes. Já falei isso por aqui, não?

Tenho recentemente trabalhado com alguns projetos mobile utilizando frameworks híbridos, como Ionic, Sencha e outros que surgem aos montes. A possibilidade de publicar tanto via browser como empacotar num cordova/phonegap dá a seu projeto uma expansibilidade generosa, podendo alcançar praticamente qualquer sistema operacional para usuários finais.

E assim vai. O fato é que, com isso em mente, pensei em fornecer uma solução nesse molde, só que para desktop. Se você é desenvolvedor web, sabe que não é suficiente abrir o arquivo html local no navegador para a execução de alguns scripts. Eles precisam ser “servidos” via HTTP. Ou seja, juntamente com o pacotão de htmls, css, js e tudo mais que seu app web tem, você precisa também de um servidor web. Para não mandar um apache para a máquina do seu usuário, ou mesmo ativar ou IIS, encontrei num canto da internet, mais especificamente o site CodePlex (se você não conhece, era esse cara quem mandava nos repositórios .NET antes do github entrar no ar) uma versão minimalista de um servidor http.

O código é bem “manual”, servindo as características de um servidor HTTP simples, respondendo a praticamente quaisquer tipos de arquivos. Os tipos servidos são definidos no web.config.  Ele vêm com alguns exemplos configurados. Para atender à minha necessidade, obtive esta pequena lista:

http://www.sitepoint.com/web-foundations/mime-types-complete-list/

E adicionei. Por fim, minha solução estava rodando dentro de um aplicativo desktop, o mesmo um console, com um servidor HTTP embutido.

Para aprendizado, vale muito. O código manipula requisições na base do socket, tanto que a instância o servidor usa a classe TcpListener, ao invés do HttpListener, como outros exemplos utilizam, conforme listarei no fim do artigo:

_myListener = new TcpListener(IPAddress.Any, Port);

O código original oferece configuração de diretório raiz e documento padrão, além da porta de escuta, tudo via web.config.

O código, com algumas alterações, pode ser visto aqui:

https://github.com/Tomamais/httpdSharpForAll

O código original:

https://httpdsharp.codeplex.com

As alternativas

Não foi só isso que encontrei. Algumas alternativas foram igualmente interessantes, mas exigiam que você manipulasse cada request manualmente. São ótimos quando você quer especializar o processamento da resposta. São eles:

NHttphttps://github.com/pvginkel/NHttp

NancyFx (selfhost) – http://nancyfx.org/

Simple HTTP Server in C# – http://www.codeproject.com/Articles/137979/Simple-HTTP-Server-in-C

Simple C# Web Server – https://codehosting.net/blog/BlogEngine/post/Simple-C-Web-Server.aspx

HttpListener Class – https://msdn.microsoft.com/en-us/library/system.net.httplistener(v=vs.110).aspx

Já se o objetivo for somente servir arquivos simples, ou mesmo um SPA, a alternativa acima é ideal!

Bom proveito!

ASP.NET – Como chamar um método server-side por Ajax no WebForms

PageMethods no ASP.NET

Primeiro, um pouco de história. Pule para se você estiver a fim de ir direto para o código.

Faz tempo que queria publicar este macete. Gosto de chamá-lo assim pois foge um pouco da linha de pensamento de quem programa há muito tempo usando WebForms. Chamadas AJAX tornaram-se algo tão natural no mundo web que quase não se pensa em sistema sem pelo menos uma chamada dessas. E, convenhamos, não é algo que o WebForms faz muito bem.

É claro que sempre tivemos o AJAX Control Toolkit (ACT) em mãos, mas assim como todo o “disfarce” que o WebForms faz sobre o protocolo HTTP, o ACT não faz diferente.

Mas e se for preciso fazer uma simples chamada a um método, mesmo que isso seja um retorno de um array de strings, ou um JSON, como fica? Há formas de fazê-lo se você pensar em um Handler puro (ASHX), mas você teria que re-estruturar toda sua aplicação só por conta disso. Mas calma, existe um jeito “bonito” de fazer isso. PageMethods!

PageMethods

Até agora não consegui encontrar uma explicação boa sobre o que são PageMethods. O que entendi foi, PageMethods são uma forma de expor funções server side da sua página ASP.NET WebForms para ser chamada por Javascript. Um exemplo é a melhor maneira de entender.

O que é preciso para usar PageMethods?

Primeiro, uma página ASPX. A página ou sua MasterPage deve possuir um controle ScripManager e nele, a propriedade EnablePageMethods definida para true.

<asp:ScriptManager ID="ScriptManager1"  runat="server" EnablePageMethods="true">
       <Scripts>
       </Scripts>
</asp:ScriptManager>

Se o ScriptManager já existir, basta acrescentar a propriedade, sem precisar mexer em referências que já existam.

Agora, a função que será chamada do lado server side. Como esta função trafegará por HTTP, o retorno desta precisa ser um tipo serializável, ou seja, que tenha uma representação em texto. No caso do exemplo, vamos retornar uma string simples. Crie a seguinte função no código da sua página:

[WebMethod]
// Get session state value.
public static string GetSessionValue(string key)
{
   return (string)HttpContext.Current.Session[key];
}
 
[WebMethod]
// Set session state value.
public static string SetSessionValue(string key, string value)
{
     HttpContext.Current.Session[key] = value;
     return (string)HttpContext.Current.Session[key];
}

Como é possível notar, o exemplo “brinca” com variáveis de servidor para provar que o trabalho está ocorrendo nele, e não no cliente. Os detalhes importantes são:

  • a função precisa retornar um tipo serializável
  • a função precisa ser static
  • a função precisa ser marcada com o atributo [WebMethod] do namespace System.Web.Services.

Por fim, o Javascript que vai chamar as funções. O código é auto explicativo. O importante a saber é que as funções criadas no código servidor serão expostas no Javascript através do objeto/function PageMethods. Assim, a função GetSessionValues criada no servidor será chamada no javascript com a sintaxe “PageMethods.GetSessionValues(parâmetros)”.

Além dos parâmetros da própria função, o PageMethods insere dos argumentos em cada uma delas, sendo eles duas funções que devem ser criadas na página, OnSucceeded e OnFailed. A primeira é invocada quando a chamada AJAX ocorre sem erros. A segunda serve exatamente para tratar erros vindos desta chamada. Veja mais detalhes no código:

// Initializes global variables and session state.
function pageLoad()
{
    PageMethods.SetSessionValue("SessionValue", Date(), 
        OnSucceeded, OnFailed);
}
 
// Gets the session state value.
function GetSessionValue(key) 
{
    PageMethods.GetSessionValue(key, OnSucceeded, OnFailed);
}
 
//Sets the session state value.
function SetSessionValue(key, value) 
{
    PageMethods.SetSessionValue(key, value, OnSucceeded, OnFailed);
}
 
// Callback function invoked on successful 
// completion of the page method.
function OnSucceeded(result, userContext, methodName) 
{
    if (methodName == "GetSessionValue")
    {
        alert("Current session state value: " + result;
    }
}
 
// Callback function invoked on failure 
// of the page method.
function OnFailed(error, userContext, methodName) 
{
    if(error !== null) 
    {
        alert( "An error occurred: " + error.get_message());
    }
}

O código pode ser colocado diretamente na página ou num arquivo Javascript separado.

Voilá! Temos AJAX de verdade do WebForms! Pelo menos quase isso.

Referências

http://www.asp.net/ajax/documentation/live/ViewSample.aspx?sref=Sys.Net.PageMethod/cs/PageMethod.aspx

DotNetNuke – Efetuando o reset na senha do host

DNN

Já falei sobre o DotNetNuke por aqui. Devo ter comentado também o quanto gosto dele. Enfim, trabalho com este CMS desde a versão 2, quando ainda havia a opção de rodar usando banco de dados em Access (isso mesmo). Você pode ler tudo o que precisa saber sobre ele no site oficial do produto: http://www.dnnsoftware.com/.

Pois, para quem vive com ferramenta, passa por alguns problemas que a área de administração não consegue resolver. Nem mesmo apelando para a pessoal da infra. Resta codificar. Uma dessas situações é quando se perde a senha do usuário host, que é o principal usuário do sistema. Quando isso acontece, um truque pouco utilizado é codificar uma página ASP.NET, seja em C# ou VB.NET com as rotinas necessárias para executar o que é necessário. Vou deixar para explicar a façanha em outro post, deixando abaixo o código que você precisa colocar dentro de um ASPX para redefinir a senha do usuário ‘host’:

<!DOCTYPE html>
<%@ Page Language="C#" %>
<script runat="server">
	void Page_Load(object sender, System.EventArgs e)
	{
		DotNetNuke.Entities.Users.UserInfo user = DotNetNuke.Entities.Users.UserController.GetUserByName("host");
 
		if (user != null)
		{
			DotNetNuke.Entities.Users.UserController.ResetPasswordToken(user);
			var passwordChanged = DotNetNuke.Entities.Users.UserController.ChangePasswordByToken(user.PortalID, user.Username, "[novasenhadohost]", user.PasswordResetToken.ToString());
 
			if(passwordChanged)
			{
				Response.Write("Senha alterada com sucesso");
			}
			else
			{
				Response.Write("Não foi possível alterar a senha.");
			}
 
		}
		else
		{
			Response.Write("Usuário não encontrado");
		}
 
	}
</script>
<html lang="pt-BR">
	<head>
		<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
		<title>Redefinindo a senha do host</title>
	</head>
 
	<body>
	</body>
</html>

É tudo o que você precisa. Basta colocar a página na raiz do seu site DNN e a senha do host será redefinida para o que estiver no lugar da string “[novasenhadohost]”. Um baita salva vidas.

O código foi testado nas versões 5, 6 e 7 do DotNetNuke.

Bom proveito!