Arquivo da categoria: Desenvolvimento

Novidades, críticas, comentários sobre o desenvolvimento e programação de sistemas, assunto que tanto agrada este autor.

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!

Sencha Touch – Problema no encoding após o build via Secha CMD

Sencha CMD

Hey ho! Festa! Este é meu primeiro post sobre Sencha Touch! Estou longe de ser um especialista, mas tenho trabalhado em um projeto que me fez estar tão envolvido com o framework que estava louco para dar algumas dicas sobre ele, principalmente sobre problemas.

Sim, como não podia ser diferente, acabei herdando um sistema legado que me fez enfretar mais problemas do que novas implementações. Tutoriais sobre como iniciar não faltam e vou deixar aqui a recomendação da excelente série de vídeos feitos pela carismática e compentente Loiane Groner, um nome de expressão internacional quando o assunto é ExtJS (base do Sencha) e Sencha Touch:

Curso de Sencha Touch 2 – Gratuito

Bom, estou aqui para falar de problemas, e possíveis soluções.

Para quem encara as rotinas de build do Sencha CMD, deve ter notado que a partir da versão 5.1.Xm no Windows (e só no Windows), o build feito gera o resultado com encoding ANSI ao invés do que foi configurado na aplicação. Isso faz que com que os caracteres quebrem. Não há o que fazer, a não ser que você mexa nos arquivos minificados, o que é humanamente IMPOSSÍVEL!

A recomendação, feita pelo próprio fórum oficial do Sencha é fazer o downgrade do Sencha CMD. Quase tive um treco ao ler isso. A parte boa é que existem duas saídas para se manter na última versão do CMD. Usar um Mac ou Ubuntu.

Como a primeira alternativa depende de algumas cifras, recomendo a segunda, instalado via VirtualBox. Os dois são free, portanto, sem problemas de licença aqui.

Segundo informações da comunidade, o bug já está corrigido na versão beta do CMD. Até lá, é sobreviver com o que se tem.

O post que discute o problema pode ser visto aqui:

https://www.sencha.com/forum/showthread.php?297673-Bug-Incorrect-encoding-on-concatenated-JS-file-in-Sencha-Cmd-5.1.1.39&langid=4

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!