Arquivos da categoria: ASP.NET

Iniciando em Single Page Application – SPA

SPASPA – Single Page Application é uma novo modelo de desenvolvimento de aplicações Web e mobile que vem ganhando destaque em grandes empresas como Microsoft, Google, Twitter, Facebook, etc.

SPA basicamente significa codificar menos no server-side e mais no client-side. Ou seja, a aplicação estará contida toda ou quase toda no cliente (dentro do navegador Web). É praticamente uma aplicação Desktop rodando sob o navegador.

Vantagem:

1 – balanceamento da responsabilidade da execução entre cliente e servidor (agora não é só mais responsabilidade do servidor);
2 – menos código do servidor, e mais responsabilidade no cliente;
3 – melhorar a experiência ao usuário (UX) criando interface com usabilidade moderna e de fácil entendimento do usuário;
4 – menor consumo de banda, pois as cargas de dados são feitas por demanda e por AJAX.

O grande ator de app SPA é o código Javascript executado no cliente. Toda a aplicação pode ser construída simplesmente manipulando o DOM – Document Object Model de forma nativa, ou com o uso de bibliotecas e frameworks Javascript que auxiliam na construção da aplicação. Estas bibliotecas e frameworks fornecem recursos para manipulação dinâmica do DOM, definição de templates de tela, chamadas assincronas ao servidor, organização do código Javascript, etc. Dentres as diversas bibliotecas JS que surgem a todo momento, as mais difundidas na comunidade de progamadores estão: BACKBONE, EMBER, ANGULARJS e KNOCKOUT.

No lado servidor, temos a execução das linguagens tradicionais como PHP, ASP.NET, JSP, etc, trabalhando também de forma tradicional, servindo arquivos, acessando a banco de dados, tratando as regras de negócios que não podem estar no código JS por questões de segurança. E é neste lado (servidor) que podemos utilizar a arquitetura REST – Representational State Transfer para fornecer serviços do servidor para nossa aplicação SPA. É comum encontrar aplicação SPA utilizando serviços RESTFul. Uma aplicação no servidor que utiliza a arquitetura REST para servir serviços, então é chamada de RESTFul.

Ao construir uma aplicação utilizando a arquitetura REST, o protocolo HTTP é usado em sua essência, utilizando os verbos (ou métodos de requisição ao servidor): GET, POST, PUT e DELETE (estes são os mais comuns), e cada um deles indica uma determinada ação a ser executada em um recurso específico do servidor.

  • GET: Está requisitando ao serviço um determinado recurso, por exemplo, uma listagem de dados;
  • POST: Indica ao serviço que a ele deve receber o recurso que está sendo enviado e adicionar em algum repositório;
  • PUT: Indica que ao serviço que o recurso que está sendo enviado deve ser alterado se ele já existir, ou ainda, pode ser adicionado caso ele ainda não exista;
  • DELETE: Indica que o serviço deve excluir o recurso.

Pensando em banco de dados, temos o seguinte entendimento:

  • GET: Recupera dados [select];
  • POST: Realiza a inserção de dados [insert];
  • PUT: Realiza a alteração de dados [update];
  • DELETE: Realiza a exclusão de dados [delete].

WebAPI é o nome dado a solução da Microsoft dentro do .NET Framework para o desenvolvimento de serviços que utilizam o conceito REST.

Criando o projeto

No VisualStudio 2013, ao criar um projeto Web, está disponível opção para seleção do template WebAPI, como é a ideia deste post é relatar a criação de app SPA, então o template selecionado deverá ser Single Page Application, que é um projeto WebAPI preparado para receber as programações SPA:

projeto_tipo_spa

Sugestão da arquitetura do projeto:

spa_webapi_arqproj

 

  • pasta app: contém os arquivos que formam a aplicação que rodará no cliente, de fato a Single Page Application;
  • pasta app\controllers: controllers do angularjs;
  • pasta app\view: views do angularjs;
  • app\app.js: configuração da aplicação no cliente;
  • pasta App_Start: classes de configuração da aplicação no servidor;
  • pasta Content: CSS da aplicação utilizando nas views (app\views);
  • pasta Controllers: Classes controladoras a nível de servidor. É de fato os serviços RESTful;
  • pasta Script: Arquivos JS da aplicação;
  • index.html: Raiz da aplicação. Será o único arquivo HTML enviado do servidor ao cliente.

No arquivo WebApiConfig.cs (da pasta App_Start) contém a configuração das rotas da aplicação:

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

Toda chamada a um método terá a URL assim: http://www.meusite.com.br/api/metodohttp/parametro.

Na configuração da api é importante padronizar o tipo de entrada e saída de dados. Para padronizar como JSON fica assim:

//padronizar JSON como retorno
config.Formatters.Remove(config.Formatters.XmlFormatter);

// Use camel case para serializar/deserializar JSON data.
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));

Um projeto WebAPI ou SPA segue praticamente a mesma estrutura do projeto MVC. A diferença está na herança das classes Controllers, pois ao invés de ser herdadas da classe Controller, são herdadas da classe abstrata ApiController.

Esta classe dispõem dos recursos necessários para o desenvolvimento de serviços RESTful. Nela estarão os métodos implementados para receber requisições de acordo com os verbos HTTP: GET, POST, PUT e DELETE.

Criando um controller

Toda classe controller deve estar na pasta Controllers e deve ter como sufixo a palavra “controller”:

  • ClienteController
  • PessoaController
  • ProdutoController

Para usar o assistente para criar a classe controller, basta adicionar a classe a partir do menu de contexto (botão direito do mouse) da pasta Controller:

spa_webapi_controller

Exemplo de classe gerada pelo assistente (o método GET foi alterado):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace SPAWebAPI.Controllers
{
    public class ClienteController : ApiController
    {
        // GET api/cliente
        public object Get()
        {
            return new { a = 1, b = 2};
        }

        // GET api/cliente/5
        public string Get(int id)
        {
            return "value";
        }

        // POST api/cliente
        public void Post([FromBody]string value)
        {
        }

        // PUT api/cliente/5
        public void Put(int id, [FromBody]string value)
        {
        }

        // DELETE api/cliente/5
        public void Delete(int id)
        {
        }
    }
}

Invocando um método da classe ClienteController com AngularJS

var req = $http({
    url: '/api/Cliente'
});

req.success(function (data, status, headers, config, statusText) {

    console.log(data.a);
    console.log(data.b);

});

req.error(function (data, status, headers, config, statusText) {
    console.log(status);
});

Consumindo WebServices sem adicionar referências no VisualStudio

aspnet-tutorial1Olá pessoal.

Recentemente precisei consumir vários WebServices num mesmo projeto, sendo não queria criar uma referência estática pelo VS com cada um deles.
Pesquisando sobre essa necessidade, me deparei com o código abaixo. É uma classe capaz e invocar WebServices manualmente, montando a mensagem SOAP (inclusive com parâmetros) e enviando ao servidor e recuperando o retorno.

    internal class WebService
    {
        public string Url { get; set; }
        public string MethodName { get; set; }
        public Dictionary<string, string> Params = new Dictionary<string, string>();
        public XDocument ResultXML;
        public string ResultString;

        public WebService()
        {

        }

        public WebService(string url, string methodName)
        {
            Url = url;
            MethodName = methodName;
        }

        /// <summary>
        /// Invokes service
        /// </summary>
        public void Invoke()
        {
            Invoke(false);
        }

        /// <summary>
        /// Invokes service
        /// </summary>
        /// <param name="encode">Added parameters will encode? (default: true)</param>
        public void Invoke(bool encode)
        {
            string soapStr =
                @"<?xml version=""1.0"" encoding=""utf-8""?>
                  <soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""
                     xmlns:xsd=""http://www.w3.org/2001/XMLSchema""
                     xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
                     <soap:Body>
                         <{0} xmlns=""http://tempuri.org/"">
                          {1}
                        </{0}>
                     </soap:Body>
                  </soap:Envelope>";

            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(Url);
            req.Headers.Add("SOAPAction", "\"http://tempuri.org/" + MethodName + "\"");
            req.ContentType = "text/xml;charset=\"utf-8\"";
            req.Accept = "text/xml";
            req.Method = "POST";

            using (Stream stm = req.GetRequestStream())
            {
                string postValues = "";
                foreach (var param in Params)
                {
                    if (encode)
                        postValues += string.Format("<{0}>{1}</{0}>", HttpUtility.UrlEncode(param.Key), HttpUtility.UrlEncode(param.Value));
                    else
                        postValues += string.Format("<{0}>{1}</{0}>", param.Key, param.Value);
                }

                soapStr = string.Format(soapStr, MethodName, postValues);
                using (StreamWriter stmw = new StreamWriter(stm))
                {
                    stmw.Write(soapStr);
                }
            }

            using (StreamReader responseReader = new StreamReader(req.GetResponse().GetResponseStream()))
            {
                string result = responseReader.ReadToEnd();
                ResultXML = XDocument.Parse(result);
                ResultString = result;
            }
        }

    }

Na hora de usar fica assim:

WebService ws = new WebService("service_url", "method_name");
ws.Params.Add("param1", "value_1");
ws.Params.Add("param2", "value_2");
ws.Invoke();
Response.Write(ws.ResultString);

Após invocar o WS basta acessar as propriedades ResultString ou ResultXML para recuperar o retorno no formato desejado.

Achei bem bacana a solução, ainda mais por dispensar a criação de referências diretamente no VisualStudio.

Fonte: http://stackoverflow.com/questions/9482773/web-service-without-adding-a-reference

ASP.NET Routing

aspnet-tutorial1O uso de URL amigáveis nos sites vem aumentando, principalmente após o surgimento do SEO – Search Engine Optimization. Este tipo de URL facilita a indexação pelos motores de busca e também para o usuário relembrar a URL que acessou.

Em ASP.NET a construção de URL amigaveis se dá por meio de Routings. Numa aplicação Web sem mapeamento de rotas, normalmente a solicitação de um navegador ocorre para um arquivo físico (página aspx): http://www.meusite.com.br/produtos.aspx?categoria=1001, sendo que a programação contida na página recupera o parâmetro por QueryString para tratar de forma dinâmica o conteúdo a ser enviado ao cliente.

Ao trabalhar com rotas, define-se padrões na organização da URL, não especificando o nome da página física que tratará a requisição, diferente do citado acima.

Uma sugestão de URL amigável para a URL tratada acima: http://www.meusite.com.br/produtos/categoria/informatica/smartphone, onde o padrão é http://www.meusite.com.br/produtos/categoria/{nome da categoria}/ {nome da subcategoria}. Desta forma, não é identificado o arquivo físico e a URL ainda fica mais agradável aos olhos do usuário.

Para implementar rotas em ASP.NET, o primeiro passo é a inclusão do arquivo global.asax ao projeto. O global.asax é uma classe que trata eventos a nível de aplicação e sessão, como por exemplo: quando a aplicação é iniciada ou finalizada, quando um sessão é criada ou destruída etc…

Os padrões de rotas devem ser especificados no evento Application_Start no global.asax, evento que ocorre quando a aplicação é iniciada.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Routing;
using System.Web.Security;
using System.Web.SessionState;

namespace ExemploRouting
{
    public class Global : System.Web.HttpApplication
    {

       protected void Application_Start(object sender, EventArgs e)
       {

       }

    }
}

No global.asax temos acesso ao objeto RouterTable que expõe a propriedade Routes, é nesta propriedade que é realizado os registro das rotas da aplicação através do método MapPageRoute.

O método MapPageRoute dá suporte a várias sobrecargas, a mais simples, recebe por parâmetro (1) o nome da rota, (2) o formato/regra da rota, (3) a página física que tratará a requisição da rota, (4) e a indicação se haverá verificação de permissões de segurança para rota (se false, todos os usuários tem acesso e se true, apenas os usuários identificados no web.config).

Um exemplo para criar a rota http://www.meusite.com.br/produtos/categoria/subcategoria:

RouteTable.Routes.MapPageRoute(&quot;rotaprodutos&quot;, &quot;produtos/categoria/{categoria}/{subcategoria}&quot;, &quot;~/produtos.aspx&quot;, false);

A expressão {categoria} e {subcategoria} indicam que a rota terá dois valores dinâmicos (espécie parâmetros) que poderão ser recuperados pela página física.

Na regra acima, a requisição para http://www.meusite.com.br/produtos/categoria/informatica/smartphone será direcionada para a página produtos.aspx que receberá como parâmetro os valores “informatica” e “smartphone”, indicando a categoria e subcategoria.

Na página, os parâmetros são recuperados pela propriedade Values do objeto global RouteData, desta forma:

Response.Write(RouteData.Values[&quot;categoria&quot;]);
Response.Write(RouteData.Values[&quot;subcategoria&quot;]);

Para finalizar, podemos adicionar um quinto parâmetro ao método MapPageRoute, que define o valor padrão dos parâmetros da rota quando não fornecidos:

RouteTable.Routes.MapPageRoute(&quot;rotaprodutos&quot;, &quot;produtos/categoria/{categoria}/{subcategoria}&quot;, &quot;~/produtos.aspx&quot;, false, new RouteValueDictionary { { &quot;categoria&quot;, &quot;geral&quot; }, { &quot;subcategoria&quot;, &quot;todas&quot; } });

Neste exemplos, os valores padrões para categoria e subcategoria será “geral” e “todas”, respectivamente.

Também é posível criar regras de rotas diretamente no IIS (http://www.iis.net/learn/extensions/url-rewrite-module/creating-rewrite-rules-for-the-url-rewrite-module).

Fontes:

  • ASP.NET 4.5 – Curso Completo – Luís Abreu
  • http://msdn.microsoft.com/en-us/library/vstudio/cc668177(v=vs.100).aspx

Chamadas XMLHttpRequest (AJAX) enviando JSON para páginas aspx ou GenericHandler – Deserialização manual

json160 csharplogoOlá pessoal,

Realmente é muito simples realizar uma chamada XMLHttpRequest (AJAX) para um WebMethod ASP.NET. E mais fácil ainda é enviar dados no formato JSON para o WebMethod, pois por padrão o WebMethod deserealizada a string JSON conforme seus parâmetros.

Mas quando não temos um WebMethod para receber os dados no formato JSON e fazer todo o trabalho de sujo de deserialização? Por exemplo, ao fazer chamadas XMLHttpRequest para uma página ou um Generic Handler passando dados no formato JSON. Nesta situação é necessário realizar a deserialização dos dados manualmente, vamos a um exemplo.

Chamada XMLHttpRequest no lado cliente:

var request = $.ajax({
type: &quot;POST&quot;,
dataType: &quot;json&quot;,
url: &quot;/meusite/processa.ashx&quot;,
cache: false,
data: JSON.stringify({ p1: &quot;oi&quot;, p2: 1000, vet: [{ vp1: {vp2: &quot;xxxx&quot;}},2] })

});

request.done(function (r) {
console.log(r);
});

request.fail(function () {
alert(&quot;Não foi possível processar sua requisição.&quot;);
});

O código acima utiliza a biblioteca jQuery para encapsular o uso da biblioteca javascript XMLHttpResquest e enviar dados ao servidor. Em sua configuração, a propriedade “URL” indica um GenericHandler no servidor (processa.ashx), mas que também pode ser substituído por uma página aspx. E a propriedade “data” foi configurada com um objeto literal com propriedades simples e complexas, que antes de ser enviado ao servidor será transformando numa string JSON pelo método JSON.stringify.

No lado servidor (no GenericHandler ou no método page_load da página), a recepção dos dados fica assim:

JavaScriptSerializer jss = new JavaScriptSerializer();
string json = new StreamReader(context.Request.InputStream).ReadToEnd();

Dictionary&lt;string, object&gt; values = jss.Deserialize&lt;Dictionary&lt;string, object&gt;&gt;(json);

string p1 = values[&quot;p1&quot;].ToString();
int p2 = Convert.ToInt32(values[&quot;p2&quot;]);

var vet = (ArrayList)values[&quot;vet&quot;];
var vp1 = ((Dictionary&lt;string, object&gt;)vet[0])[&quot;vp1&quot;];
var vp2 = ((Dictionary&lt;string, object&gt;)vp1)[&quot;vp2&quot;];

No código de servidor acima, a propriedade InputStream do objeto Request representa o conteúdo do corpo de entrada de conteúdo HTTP vindo do cliente, portanto, representa a string JSON enviada pelo cliente.

O inputString é recuperado e deserializado em um objeto Dictionary (espécie de lista indexada por chaves). Cada propriedade da string JSON torna-se uma chave do dicionário, sendo facilmente acessada:

int p1 = values[&quot;p1&quot;].ToString();
int p2 = Convert.ToInt32(values[&quot;p2&quot;]);

E também podemos acessar estruturas JSON mais complexas, como é o caso da propriedade “vet”, que mantém um vetor, cujo seu índice 0 (zero) contém outro objeto JSON.

vet: [{ vp1: {vp2: &quot;xxxx&quot;}},2]

Após recuperação do vetor, foi necessário converte o objeto de índíce 0 (zero) em outro Dictionary, desta forma, as propriedades do objeto contido no índice 0 (zero) da propriedade “vet” são acessadas por chaves do Dictionary.

var vp1 = ((Dictionary&lt;string, object&gt;)vet[0])[&quot;vp1&quot;];
var vp2 = ((Dictionary&lt;string, object&gt;)vp1)[&quot;vp2&quot;];

E fim.

Coleções em C# usando List

csharplogo

Nas linguagens de programação, o termo coleção é utilizado para definir estruturas capazes de agrupar objetos. Um simples vetor/array pode ser definido como uma coleção, neste caso, estática.

Em C# é facilmente possível criar coleções dinâmicas com o classe List<T>, disponível no namespace System.Collections.Generic.

Uma coleção gerada com List<T> fornece uma ótima opção, quando precisamos agrupar tipos de objetos (por exemplo, classes) de forma dinâmica e eficiente, e com métodos que possibilitam filtrar, ordenar e seus itens.

Vamos aos exemplos:

1 – Criando uma classe.

public class Pessoa
{
    int _id;

    public int Id
    {
        get { return _id; }
        set { _id = value; }
    }
    string _nome;

    public string Nome
    {
        get { return _nome; }
        set { _nome = value; }
    }

    public Pessoa()
    {
        _id = 0;
        _nome = &quot;&quot;;
    }

    public Pessoa(int id, string nome)
    {
        this._id = id;
        this._nome = nome;
    }
}

2 – Criando e manipulando uma coleção da classe Pessoa (deve referenciar o namespace System.Collections.Generic).

using System.Collections.Generic;

//Criando uma lista que agrupará objetos da classe Pessoa.
List&lt;Pessoa&gt; pessoas = new List&lt;Pessoa&gt;();

//Adicionando objetos (tipo Pessoa) na lista.
pessoas.Add(new Pessoa(1, &quot;Andre&quot;));
pessoas.Add(new Pessoa(2, &quot;Brenda&quot;));

//Percorrendo a lista.
foreach (Pessoa p in pessoas)
{
   Console.WriteLine(p.Nome);
}

//Localizando uma pessoa.
Pessoa pessoa = pessoas.Find(delegate(Pessoa p1) { return p1.Id == 2; });

//Localizando várias pessoas que contenham no nome as letras &quot;nd&quot; (neste caso, o retorno é uma outra List&lt;Pessoas&gt; com as pessoas localizadas).
List&lt;Pessoa&gt; pessoasLocalizadas = pessoas.FindAll(delegate(Pessoa p1) { return p1.Nome.Contains(&quot;nd&quot;); });


//Removendo um item da lista pela sua posição.
pessoas.RemoveAt(0);

Mais detalhes em http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx.

Até…

Gerando estruturas JSON em C# e ASP.NET

json160Dando continuidade ao post Introdução ao JSON – Javascript Object Notation, mostro agora como construir em C# as estruturas dos exemplos utilizados no post anterior.

No C# podemos criar objetos de tipo anônimos (anonymous types) para definir a estrutura e dados, e depois realizar a serialização para o formato JSON.

Vamos aos exemplos:

1 – Criando um objeto.

public static string retornaObjetoJSON()
{
    //{“nome” : “Bill”, “idade” : 32, “salario”: 121232.67}

    var obj = new { nome = "Bill", idade = 32, salario = 121232.67};

    JavaScriptSerializer js = new JavaScriptSerializer();
    string strJson = js.Serialize(obj);
    return strJson;
}

2 – Criando um array.

public static string retornaArrayJSON()
{
    //["Huguinho","Zezinho","Luizinho", 3]

    var objVet = new object[] { "Huguinho", "Zezinho", "Luizinho", 3 };

    JavaScriptSerializer js = new JavaScriptSerializer();
    string strJson = js.Serialize(objVet);
    return strJson;
}

3 – Criando um array de objetos.

public static string retornaVetorDeObjetoJSON()
{
    /*
        [{ "nome" : "Huguinho", "idade" : 10 },
        { "nome" : "Zezinho", "idade" : 12 },
        { "nome" : "Luizinho", "idade" : 10 }]
    */

    var objVet = new object[] { new { nome = "Huguinho", idade = 10 },
                                new { nome = "Zezinho", idade = 12 },
                                new { nome = "Luizinho", idade = 10 }};

    JavaScriptSerializer js = new JavaScriptSerializer();
    string strJson = js.Serialize(objVet);
    return strJson;
}

4 – Criando um objeto contendo um propriedade array de objetos.

public static string retornaObjetoComVetorJSON()
{
    /*
        {"tio" : "Pato Donald",
        "idade" : 40,
        "sobrinhos" :
                [{ "nome" : "Huguinho",     "idade" : 10 },
                { "nome" : "Zezinho", "idade" : 12 },
                { "nome" : "Luizinho", "idade" : 10 }]
        }
    */

    var obj = new {tio = "Pato Donald",
                    idade = 40,
                    sobrinhos = new object[] { new { nome = "Huguinho", idade = 10 },
                                                new { nome = "Zezinho", idade = 12 },
                                                new { nome = "Luizinho", idade = 10 }}
                    };

    JavaScriptSerializer js = new JavaScriptSerializer();
    string strJson = js.Serialize(obj);
    return strJson;
}

A biblioteca System.Web.Script.Serialization é a responsável por realizar a serialização dos objetos anônimos.

Logo mais num outro post mostro como realizar chamadas assíncronas por Javascript ao JSON gerado no C# no servidor.

Até…

Habilitando suporte para HTML 5 no VisualStudio 2010

Para habilitar suporte para HTML 5 no VisualStudio 2010 é necessário instalar o Service Pack 1, disponível em

http://www.microsoft.com/download/en/details.aspx?id=23691.

Após sua instalação, abra o Visual Studio e no menu TOOLS > OPTIONS, e selecione grupo HTML Editor selecionando o item VALIDATION, marcando o TARGET como HTML5.

Ao criar um novo arquivo o intelisense mostra as novas tags do HTML 5.

Enquanto ainda não decoramos as novas implementações do HTML 5, é possível facilmente fazer sua validação por meio da barra HTML Sourcing Editing de validação do VS.

Agora é só brincar.

UpdatePanel e JQuery

Para quem usa ASP.NET é comum o uso do UpdatePanel para realizar atualizações parciais. Atualmente também é comum o uso JQuery.

O problema é quando os dois recursos devem conviver juntos. O problema que ocorre é que após a atualização parcial da página pelo UpdatePanel a implementação JQuery deixa de funcionar, provavelmente devido a estrutura da página ter mudado após a atualização.

Uma forma que encontrei, é executar as funções Javascript que usam JQuery novamente após a renderização pelo UpdatePanel.

No ASP.NET Ajax é possível gerenciar a renderização parcial da página através da classe PageRequestManager. A classe define eventos que podem ser usados na personalização da renderização parcial. O seu metódo getInstance() recupera sua instância atual/ativa e seu método add_endRequest permite adicionar uma chamada a uma função Javascript exatamente após o fim da renderização parcial, é neste momento que devemos chamar a função Javascript que mantem código JQuery.

Exemplo:

$(document).ready(function () {

	//Inicializando na após a carga da página
	inicializa();

	//função com o código JQuery
	function inicializa()
	{
		$(&quot;buttonX&quot;).click(function () {
			fazAlgumaCoisa();
		});
	}

	function fazAlgumaCoisa()
	{
		alert('Feito');
	}

	//Recuperando a instância ativa da classe PageRequestManager.
       var prm = Sys.WebForms.PageRequestManager.getInstance();
       if (prm != null) {
   	   //Registrando uma chamada a função inicializa() após o fim da renderização parcial da página.
           prm.add_endRequest(function () {
               inicializa();
           });
       }
})

Mais informações sobre a classe PageRequestManager em http://msdn.microsoft.com/pt-br/library/bb311028(v=VS.90).aspx

Até mais.

Upload de arquivos em ASP.NET

Pessoal.

Segue um exemplo rápido de como enviar arquivos ao servidor em ASP.NET usando o servercontrol UploadFile.

HTML:

&lt;form id=&quot;form1&quot; runat=&quot;server&quot;&gt;
&lt;div&gt;
    &lt;asp:FileUpload ID=&quot;FileUpload1&quot; runat=&quot;server&quot; /&gt;
    &lt;asp:Button ID=&quot;btnEnviar&quot; runat=&quot;server&quot; Text=&quot;Enviar&quot;
        onclick=&quot;btnEnviar_Click&quot; /&gt;
    &lt;asp:Label ID=&quot;lMsg&quot; runat=&quot;server&quot;&gt;&lt;/asp:Label&gt;
&lt;/div&gt;
&lt;/form&gt;

C#:

        string caminhoArq = &quot;&quot;;
        try
        {
            if (FileUpload1.HasFile) //Verifica se um arquivo foi enviado
            {
                caminhoArq = Server.MapPath(&quot;~/arquivos/&quot;) + FileUpload1.FileName;
                FileUpload1.SaveAs(caminhoArq);
                lMsg.Text = &quot;Arquivo enviado com sucesso.&quot;;
            }
            else lMsg.Text = &quot;Selecione um arquivo.&quot;;
        }
        catch
        {
            lMsg.Text = &quot;Não foi possível enviar o arquivo.&quot;;
        }

O método MapPath da classe Server retorna o caminho físico do diretório “Arquivos”. É necessário pois o método SaveAs do FileUpload precisa de um caminho físico para entender onde salvar o arquivo.

É possível verificar o tamanho do arquivo enviado checando da propriedade ContentLength em FileUpload1.PostedFile. Seu valor é em bytes.


if (FileUpload1.PostedFile.ContentLength &gt; 10485760)
...

Também é possível checar o tipo do arquivo enviado. A propriedade ContentType em FileUpload1.PostedFile mantém o tipo MIME do arquivo.


if (FileUpload1.PostedFile.ContentType == &quot;application/pdf&quot;)
...

MIME Reference:

Fácil, simples, e funcional. Isso é ASP.NET.