sexta-feira, 17 de agosto de 2007

CS0030: Cannot convert type

CS0030: Cannot convert type 'ASP.login_aspx' to 'System.Web.UI.WebControls.Login'

Another issue which I found really interesting... We had an ASP.NET 2.0 application and in one of the pages (called Login.aspx) we used the Login control. It worked beautifully from the IDE (F5 or CTRL+F5), but when we deployed it on the webserver (precompiled), it showed the following error.

Compiler Error Message: CS0030: Cannot convert type 'ASP.login_aspx' to 'System.Web.UI.WebControls.Login'

Source Error:
Line 112: public login_aspx() {
Line 113: string[] dependencies;
Line 114: ((Login)(this)).AppRelativeVirtualPath = "~/Login.aspx";
Line 115: if ((global::ASP.login_aspx.@__initialized == false)) {
Line 116: dependencies = new string[1];

Source File: c:WINDOWSMicrosoft.NETFrameworkv2.0.50727Temporary ASP.NET Filescpi.operations.field.assv32f5e4c75ac0558eApp_Web_login.aspx.cdcab7d2.crjut9bu.0.cs Line: 114

Clearly, it was looking like a name conflict. We changed the name of the page class from Login to Login1 and re-deployed on the webserver and it worked fine, as expected.

Moral of the story... in 2.0, don't use Login as a class name if you intend to use the Login Control. It is not really that big a compromise, specially if you consider the functionality of Login control!! Besides, you can always name your page as Login.aspx. All you need to ensure is that, the name of the class of that page is NOT called Login.

PS. It is not that naming a class as Login WILL run into problems, but just in case you get the above error and your symptoms match, I hope this might help you...

sexta-feira, 20 de julho de 2007

Callbacks in a custom Controls

Callbacks

Callbacks allow a control or page to perform an out-of-band call back to the server in a manner that does not require the page to be posted back entirely. This means that your custom control does not cause the client browser to wait on an entire page post back and your custom control can enable rich UI functionality. You can develop a custom control that easily combines for example, web resources with client script management to make use of the call back infrastructure. To enable a call back you will:
  • Create a server-side call back event with a given signature in your custom control, (ICallbackEventHandler.PrepareCallbackEvent) that acts on an argument passed into the method<. You should call on a method that developers can override if they extend your custom control;
  • Create a server-side method that generates the result for the call back, ICallbackEventHandler.RenderCallbackResult. You should call a method that developers can override if they extenf your control. The return result will be passed to client-side script defined by your custom control;
  • Create client-side script that manages the return call or error. This will be generated through your custom control;
  • Use the callback event reference hooked up to a client-side event in your custom control.

  

public class CustomControl : CompositeControl
void ICallbackEventHandler.PrepareCallbackEvent(string
eventArgument)
{
PrepareCallBackEvent(eventArgument);
}

String ICallbackEventHandler.RenderCallbackResult()
{
return RenderCallbackResult();
}

private String _callbackEventArg;

// Do work in a protected virtual methods so that derived controls can override
protected virtual void PrepareCallBackEvent(string eventArgument)
{
_callbackEventArg = eventArgument;
}

protected virtual String RenderCallbackResult()
{
if (_callbackEventArg == "theArg")
return = "Some data";
return "Only theArg allowed!";
}

// Additional implementation

// Client script functions that handle the callback
private String sButtonCallBack = "function ButtonCallBack(result, context) { alert(result); }";
private String sButtonCallBackError = "function ButtonErrorCallBack(result, context) { alert(result); }";

protected override void OnInit(EventArgs e)
{
base.OnInit(e);

// Additional implementation

Page.ClientScript.RegisterClientScriptBlock(typeof(CustomControl),
"ButtonCallBack", sButtonCallBack, true);
Page.ClientScript.RegisterClientScriptBlock(typeof(CustomControl),
"ButtonCallBackError", sButtonCallBackError, true);
}

// Additional implementation

protected override void OnPreRender(EventArgs e) {
// Set up the OnClick event to fire an out-of band call to the handler
Attributes["OnClick"] = Page.ClientScript.GetCallbackEventReference(this,
"'theArg'", "ButtonCallback", "null", "ButtonErrorCallback", true);
base.OnPreRender(e);
}
}

Implementando Callbacks cliente sem Postbacks em páginas da Web


No modelo padrão para páginas da Web do ASP.NET, o usuário interage com uma página e clica em um botão ou executa alguma outra ação que resulta em um novo postback. A página e seus controles são recriados, o código de página é executado no servidor, e uma nova versão da página é processada para o navegador. Entretanto, em algumas situações, é útil executar código de servidor a partir do cliente sem executar um novo postback. Se o script cliente na página estiver mantendo algumas informações de estado (por exemplo, valores de variáveis locais), postar a página e obter uma nova cópia dela destrói esse estado. Além disso, postbacks de página introduzem sobrecarga de processamento que pode diminuir o desempenho e forçar o usuário a aguardar a página ser processada e recriada.


Para evitar a perda do estado do cliente e não gerar a sobrecarga do processamento de uma resposta do servidor, você pode codificar uma página da Web do ASP.NET para que ele possa fazer chamadas de retorno cliente. Em uma chamada de retorno cliente, uma função script cliente envia uma solicitação para uma página da Web do ASP.NET. A página da Web executa uma versão modificada do seu ciclo normal de vida — a página é iniciada e seus controles e outros membros são criados, e então um método especialmente marcado é chamado. O método executa o processamento que você codificou e então retorna um valor para o navegador que pode ser lido por outra função script cliente. Em todo esse processo, a página está ativa no navegador.

Vários controles do servidor Web utilizam chamadas de retorno cliente. Por exemplo, o controle TreeView utiliza chamadas de retorno cliente para implementar sua funcionalidade de preenchimento por demanda. Para obter mais informações consulte Visão geral sobre controle TreeView do Servidor Web.

Componentes de Chamadas de Retorno Cliente

Criar uma página ASP.NET que implementa chamadas de retorno é similar à criar qualquer página ASP.NET, com pequenas diferenças. O código do servidor da página deve:

  • Implementar a interface ICallbackEventHandler. Você pode adicionar essa declaração de interface para qualquer página da Web do ASP.NET.

  • Um método que implementa a interface RaiseCallbackEvent. Esse método será chamado para executar a chamada de retorno a partir do servidor.

Além disso, a página pode conter três funções script cliente que executam as seguintes ações:

  • Uma função chama um método auxiliar que realiza a solicitação real para o servidor. Nessa função, você pode executar lógica personalizada para preparar os argumentos do evento primeiro, em seguida, você pode enviar uma seqüência de caracteres como um parâmetro para o manipulador de eventos de chamada de retorno do lado do servidor.

  • Outra função recebe (é chamado por) o resultado do código do servidor que processou o evento de chamada de retorno, aceitando uma seqüência de caracteres que representa os resultados. Ela é chamada de função de chamada de retorno cliente.

  • Uma terceira função é a função auxiliar que realiza a solicitação real para o servidor, a qual é gerada automaticamente pelo ASP.NET quando você gera uma referência a essa função utilizando o método GetCallbackEventReference no código do servidor.

Ambos, chamadas de retorno e postbacks, são solicitações para a página de origem, assim, chamadas de retorno cliente e postbacks são armazenados em logs de servidores Web como uma solicitação de página.

Implementando a Interface Apropriada no Código do Servidor

Para executar com êxito o código do servidor a partir do cliente sem executar um postback, você deve implementar as interfaces apropriadas no código do servidor.

Declarando a interface ICallbackEventHandler

Você pode declarar a interface ICallbackEventHandler como parte da declaração de classe para a página. Se você estiver criando uma página code-behind, você pode declarar a interface utilizando sintaxe como demonstrado a seguir.

Visual Basic
Partial Class CallBack_DB_aspx
Inherits System.Web.UI.Page
Implements System.Web.UI.ICallbackEventHandler
C#
public partial class CallBack_DB_aspx : 
System.Web.UI.Page, System.Web.UI.ICallbackEventHandler

Se você estiver trabalhando em uma página de um único arquivo ou controle de usuário, você pode adicionar a declaração utilizando uma diretiva @ Implements na página, como nos exemplos de código a seguir:

Visual Basic
<%@ Page Language="VB" %>
<%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>
C#
<%@ Page Language="C#" %>
<%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>
NoteObservação

O nome interface diferencia maiúsculas de minúsculas.

Criando um Método Callback de Servidor

No código do servidor, você deve criar um método que implementa o método RaiseCallbackEvent e um método que implementa o método GetCallbackResult. O método RaiseCallbackEvent aceita uma única seqüência de caracteres como argumento, em vez dos dois argumentos que são normalmente utilizados com manipuladores de eventos normal. Uma parte do método pode parecer com o exemplo de código a seguir.

Visual Basic
Public Sub RaiseCallbackEvent(ByVal eventArgument As String) _
Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent
Return eventArgument & " new value"
End Sub
C#
public void RaiseCallbackEvent(String eventArgument)
{
return eventArgument + " new value";
}

O método GetCallbackResult não recebe argumentos e retorna uma seqüência de caracteres. Uma parte do método pode parecer com o exemplo de código a seguir.

Visual Basic
Public Function GetCallbackResult() As String Implements _
System.Web.UI.ICallbackEventHandler.GetCallbackResult
Return aStringValue
End Function
C#
public string GetCallbackResult()
{
return aStringValue;
}

Criando Funções Scripts Cliente

Você deve adicionar funções script cliente à página para executar duas funções: enviar a chamada de retorno para a página do servidor e receber os resultados. As duas funções script cliente são gravadas no ECMAScript (JavaScript).

Enviando a Chamada de Retorno

A função para enviar a chamada de retorno é gerada no código do servidor. A chamada de retorno real é executada por uma função de biblioteca que está disponível para qualquer página que implementa a interface ICallbackEventHandler. Você pode obter uma referência para a função de biblioteca chamando o método GetCallbackEventReference da página, que pode ser acessado através da propriedade ClientScript da página. Você então compila uma função cliente dinamicamente que inclui uma chamada para o valor de retorno do método GetCallbackEventReference. Você passa para esse método uma referência para a página (this no C# ou Me no Visual Basic), o nome do argumento pelo qual você irá passar dados, o nome da função script cliente que receberá os dados da chamada de retorno, e um argumento que passa qualquer contexto que você desejar.

Quando você tiver compilado a função, você a insere dentro da página através da chamada do método RegisterClientScriptBlock.

O exemplo de código a seguir mostra como criar dinamicamente uma função denominada CallServer que chama a chamada de retorno.

Visual Basic
Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Me.Load
Dim cm As ClientScriptManager = Page.ClientScript
Dim cbReference As String
cbReference = cm.GetCallbackEventReference(Me, "arg", "ReceiveServerData", "")
Dim callbackScript As String = ""
callbackScript &= "function CallServer(arg, context)" & "{" & cbReference & "; }"
cm.RegisterClientScriptBlock(Me.GetType(), "CallServer", callbackScript, True)
End Sub
C#
void Page_Load(object sender, EventArgs e)
{
ClientScriptManager cm = Page.ClientScript;
String cbReference = cm.GetCallbackEventReference(this, "arg", "ReceiveServerData", "");
String callbackScript = "function CallServer(arg, context) {" + cbReference + "; }";
cm.RegisterClientScriptBlock(this.GetType(), "CallServer", callbackScript, true);
}

Os nomes dos argumentos que são aceitos pela função que você está gerando devem corresponder aos nomes dos valores que você passa para o método GetCallbackEventReference.

O exemplo de código a seguir mostra algumas marcações que podem ser utilizadas para chamar a chamada de retorno e processar seu valor de retorno:

Visual Basic
<input type="button" value="Callback" 
onclick="CallServer(1, alert('Callback'))"/>
<br />
<span id="Message"></span>
C#
<input type="button" value="Callback" 
onclick="CallServer(1, alert('Callback'))"/>
<br />
<span id="Message"></span>

Recebendo a Chamada de Retorno

Você pode escrever a função cliente que recebe chamadas de retorno estaticamente na página. A função deve ser nomeada de modo a corresponder ao nome que você passa na chamada para o método GetCallbackEventReference. A função receptora aceita dois valores de seqüência de caracteres: um para o valor de retorno e um segundo valor, opcional, para o valor de contexto que é passado de volta através do servidor.


A função pode ser semelhante ao exemplo de código a seguir:

<script type="text/javascript">
function ReceiveServerData(arg, context)
{
Message.innerText = 'Processed callback.';
}
</script>


sexta-feira, 13 de julho de 2007

Tipos de arquivo no .NET


Aplicativos de site da Web podem conter uma variedade de tipos de arquivo, alguns suportados e gerenciados pelo ASP.NET, e outros suportados e gerenciados pelo servidor IIS.

A maioria dos tipos de arquivo do ASP.NET pode ser gerada automaticamente usando o item de menu Add New Item no Visual Developer da Web.

Tipos de arquivo são mapeados para aplicativos usando mapeamentos de aplicativo. Por exemplo, se você abrir um arquivo com a extensão .txt, o aplicativo bloco de notas será aberto, provavelmente porque os tipos de arquivo .txt são mapeados por padrão para notepad.exe.

Tipos de arquivo gerenciados pelo ASP.NET

Os tipos de arquivo que são gerenciados pelo ASP.NET são mapeados para o Aspnet_isapi.dll no IIS.

Tipo de arquivo Local Descrição

.asax

Raiz de aplicativo.

Normalmente um arquivo Global.asax que contém código que deriva da classe HttpApplication e representa o aplicativo.

Para obter mais informações, consulte Sintaxe Global.asax.

.ascx

Raiz do aplicativo ou uma subpasta.

Um arquivo de controle de usuário da Web que define um controle de usuário personalizado, reutilizável.

Para obter mais informações, consulte Controles de usuário ASP.NET.

.ashx

Raiz de aplicativo ou uma subpasta.

Um arquivo manipulador genérico que contém código que implementa a interface IHttpHandler para manipular todas as solicitações recebidas.

Para obter mais informações, consulte Introdução aos manipuladores HTTP.

.asmx

Raiz de aplicativo ou uma subpasta.

Um arquivo de XML Web Services que contém as classes e métodos que estarão disponíveis para outros aplicativos da Web por meio de SOAP.

Para obter mais informações, consulte XML Web Services Publishing and Deployment.

.aspx

Raiz de aplicativo ou uma subpasta.

Um arquivo de formulários da Web ASP.NET que pode conter controles da Web e lógica corporativa.

Para obter mais informações, consulte Páginas da Web ASP.NET e Controles de servidores Web do ASP.NET.

.axd

Raiz de aplicativo.

Um arquivo trace-viewer, normalmente Trace.axd.

Para obter mais informações, consulte Rastreamento no ASP.NET.

.browser

Subdiretório App_Browsers.

Um arquivo de definição de navegador usado para identificar os recursos ativados do navegador do cliente.

Para obter mais informações, consulte Controles de Servidor Web do ASP.NET e Recursos do Navegador.

.cd

Raiz de aplicativo ou uma subpasta.

Um arquivo de diagrama de classe.

Para obter mais informações, consulte Trabalhando com diagramas de classe.

.compile

subpasta Bin.

Um arquivo pré-compilado que aponta para o assembly apropriado. Tipos de arquivo executáveis (.aspx, .ascx,. master, arquivos de tema) são pré-compilados e colocados no subdiretório Bin.

Para obter mais informações, consulte Visão geral da Pré-compilação do Site da Web ASP.NET.

.config

Raiz de aplicativo ou uma subpasta.

Normalmente um arquivo de configuração Web.config que contém elementos XML cujas definições configuraram os vários recursos do ASP.NET.

Para obter mais informações, consulte Arquivos de configuração ASP.NET.

.cs, .jsl, .vb

Subpasta App_Code, ou no caso de um arquivo de code-behind para uma página ASP.NET, no mesmo diretório que a página da Web.

Arquivo de código-fonte de classe que é compilada em tempo de execução. A classe pode ser um HTTP Module, um HTTP Handler, ou um arquivo de code-behind para uma página Introdução aos manipuladores HTTP ASP.NET.

.csproj, .vbproj, vjsproj

Diretório de projeto Visual Studio.

Um arquivo de projeto de um aplicativo cliente Visual Studio.

Para obter mais informações, consulte Projects and Solutions.

.disco, .vsdisco

Subdiretório App_WebReferences.

Um arquivo de descoberta de XML Web Services usado para ajudar a localizar serviços da Web disponíveis.

Para obter mais informações, consulte XML Web Services Publishing and Deployment.

.dsdgm, .dsprototype

Raiz de aplicativo ou uma subpasta.

Um arquivo de diagrama de serviço distribuído (DSD, distributed service diagram) que pode ser adicionado a qualquer solução do Visual Studio que forneça ou consuma serviços da Web para fazer engenharia reversa da arquitetura de interações do serviço da Web.

Para obter mais informações, consulte XML Web Services Publishing and Deployment.

.dll

subpasta Bin.

Um arquivo de biblioteca de classes compilado. Como alternativa, você pode colocar o código-fonte das classes no subdiretório App_Code.

Para obter mais informações, consulte Pastas de Código Compartilhadas em Sites Web do ASP.NET.

.licx, .webinfo

Raiz de aplicativo ou uma subpasta.

Um arquivo de licença. O licenciamento permite a autores de controles ajudar a proteger propriedade intelectual, verificando se um usuário está autorizado a utilizar o controle.

Para obter mais informações, consulte HOW TO: Componentes licença e controles.

.master

Raiz de aplicativo ou subdiretório.

Uma página mestre que define o layout para outras páginas da Web no aplicativo que fazem referência ao mestre.

Para obter mais informações, consulte Páginas Mestras do ASP.NET.

.mdb, .ldb

Subdiretório App_Data.

Um arquivo de banco de dados Access.

Para obter mais informações, consulte Acessando dados com o ASP.NET.

.mdf

Subdiretório App_Data.

Arquivo de banco de dados SQL.

Para obter mais informações, consulte Acessando dados com o ASP.NET.

.msgx, .svc

Raiz de aplicativo ou uma subpasta.

Um arquivo do serviço Indigo Framework Messaging (MFx).

.rem

Raiz de aplicativo ou uma subpasta.

Um arquivo manipulador de remoting.

Para obter mais informações, consulte SOAP Message Modification Using SOAP Extensions.

.resources

Subdiretório App_GlobalResources ou App_LocalResources.

Um arquivo de recurso que contém strings que se referem a imagens, textos localizáveis, ou outros dados.

Para obter mais informações, consulte Resources in Applications ou Como: Criar Arquivos de Recursos para Sites da Web do ASP.NET.

.resx

Subdiretório App_GlobalResources ou App_LocalResources.

Um arquivo de recursos que contém strings que se referem a imagens, textos localizáveis, ou outros dados.

Para obter mais informações, consulte Resources in Applications ou Como: Criar Arquivos de Recursos para Sites da Web do ASP.NET.

.sdm, .sdmDocument

Raiz de aplicativo ou uma subpasta.

Um arquivo de modelo de definição de sistema (SDM, system definition model).

Para obter mais informações, consulte Visão geral sobre o modelo de definição do sistema (SDM).

.sitemap

Raiz de aplicativo.

Um arquivo de mapa de site que contém a estrutura do site da Web. O ASP.NET vem com um provedor de mapa de site padrão que usa arquivos de mapa de site para facilmente exibir um controle de navegação em uma página da Web.

Para obter mais informações, consulte Navegação site ASP.NET.

.skin

Subdiretório App_Themes.

Um arquivo de skin usado para determinar formatação de exibição.

Para obter mais informações, consulte Temas e Aparências do ASP.NET.

.sln

Diretório de projeto do Visual Web Developer.

Um arquivo de solução para um projeto Visual Web Developer.

Para obter mais informações, consulte Projects and Solutions.

.soap

Raiz de aplicativo ou uma subpasta.

Um arquivo de extensão SOAP.

Para obter mais informações, consulte SOAP Message Modification Using SOAP Extensions.




quinta-feira, 12 de julho de 2007

Armazenando imagens na base de dados e exibí-la em GridView


Introduzindo imagens na base de dados e indicá-la em GridView com Handler.ashx


Introdução
Este artigo explica o método de introduzir imagens na base de dados do usuário do SQL e exibí-la em um controle do ASP.NET GridView com a ajuda de Handler.aspx.

Descrição
Você viu alguma aplicação ou Web Site sem imagens? Não, você não viu. As imagens desempenham um papel principal no desenvolvimento da aplicação da internet. Ou é um web site de HTML estático ou uma aplicação avançada de RAD, tudo é construído junto com imagens. Se sua aplicação for um site de comércio eletrônico ou portal da galeria de imagens, definitivamente você tem que sofrer para guardar as imagens em lugares diferentes com tamanhos e tipos diferentes. E não é um trabalho o fácil controlar aquelas imagens não desejadas e antigas a serem removidas da pasta de imagens. Assim o seu tempo e esforço é claramente consumindo.

Para fazer sua tarefa mais fácil, este artigo explica os métodos para armazenar as imagens no banco de dados. Há muitas vantagens de conservar as imagens na base de dados. A vantagem principal é gerência fácil das imagens. Você pode controlar o número e o tamanho das imagens armazenadas em sua base. Você pode remover todas as imagens desnecessárias da base de dados em um único comando sql e você pode fazer o backup das imagens facilmente.

Introduzindo a imagem na base de dados

Para começar, deixe-me explicar a estrutura da tabela da base de dados que vamos usar para introduzir a imagem. A tabela que você criará para armazenar a imagem deve conter uma coluna do tipo de dados IMAGE. Este tipo de dados de imagem é de dados binários Variable-length com um comprimento máximo de 2^31 - (2.147.483.647) bytes 1. Para armazenar a imagem nesta coluna nós a converteremos em um array binário com a ajuda de algumas classes do namespace IO para então introduzí-la na tabela. Para demonstração, nós vamos criar uma tabela com nome ImageGallery com as quatro colunas na seguinte estrutura:

Nome da coluna Descrição Tipo de dados
Img_Id Coluna da identidade para a identificação da imagem uniqueidentifier
Image_Content Armazenar a imagem no formato binário image
Image_Type Armazenar o formato da imagem (i.e. JPEG, GIF, PNG, etc.) varchar
Image_Size Armazenar o tamanho da imagem bigint

Depois que nós criamos a tabela na base de dados, nós podemos começar a parte de codificação.

1. Abra sua aplicação web no Visual Studio 2005, arraste um controle do Upload da arquivo e um controle da Botão na Web page.
2. No code-behind adicione o namespace System.IO.

using System.IO;

3. No evento de Button1_Click do botão, escrever o seguinte código:
if (FileUpload1.PostedFile != null && FileUpload1.PostedFile.FileName != "")
{
byte[] myimage = new byte[FileUpload1.PostedFile.ContentLength];
HttpPostedFile Image = FileUpload1.PostedFile;
Image.InputStream.Read(myimage, 0, (int)FileUpload1.PostedFile.ContentLength);


SqlConnection myConnection = new SqlConnection(“Your Connection String”);
SqlCommand storeimage = new SqlCommand("INSERT INTO ImageGallery " +"(Image_Content, Image_Type, Image_Size) " +" values (@image, @imagetype, @imagesize)", myConnection);
storeimage.Parameters.Add("@image", SqlDbType.Image, myimage.Length).Value = myimage;
storeimage.Parameters.Add("@imagetype", SqlDbType.VarChar, 100).Value = FileUpload1.PostedFile.ContentType;
storeimage.Parameters.Add("@imagesize", SqlDbType.BigInt, 99999).Value = FileUpload1.PostedFile.ContentLength;

myConnection.Open();
storeimage.ExecuteNonQuery();
myConnection.Close();
}

Para fazer o upload da imagem de qualquer local (seu HD) para o servidor, nós temos que usar o objeto de HttpPostedFile. Apontar para o arquivo enviado ao objeto de HttpPostedFile. Então o método de InputStream.Read lerá o conteúdo da imagem por uma seqüência dos bytes do Stream. Assim o myimage conterá a imagem como dados binários. Agora nós temos que passar estes dados no objeto de SqlCommand, que os introduzirá na tabela da base de dados.

Exibindo a imagem em um GridView com Handler.ashx

Até agora, o artigo explicou como introduzir imagens na base de dados. A imagem está na base de dados no formato de dados binário. Recuperar estes dados em um Web page de ASP.NET é razoavelmente fácil, mas exibí-lo não é tão simples. O problema básico é que para mostrar uma imagem em uma página aspx, você precisa adicionar um Tag da imagem que fará ligação a um arquivo de imagem através do atributo src ou você precisará pôr um controle da imagem em sua página e especificar a propriedade ImageUrl.

Por exemplo:
<asp:image Runat="server" ImageUrl="YourImageFilePath" ID="Image1" />

Infelizmente, esta solução não funcionará se você necessitar mostrar dinâmicamente dados da imagem. Embora você possa ajustar o atributo de ImageUrl no código, você não tem nenhuma maneira ajustar programmatically o conteúdo da imagem. Você poderia primeiramente gravar os dados do arquivo da imagem no HD do web server, mas essa solução seria dramaticamente mais lenta, desperdiçaria espaço, e levanta a possibilidade de erros da concorrência se os pedidos múltiplos estivessem servidos ao mesmo tempo e todos tentassem escrever o mesmo arquivo.

Nestas situações, a solução é usar um recurso separado de ASP.NET que retorne os dados binários diretamente da base de dados. Aqui a classe HTTP Handler vai nos ajudar.

O que é um Handler?

O ASP.NET HTTP Handler é uma classe simples que permita que você processe um pedido e retorne uma resposta ao browser. Simplesmente nós podemos dizer que um handler é responsável para cumprir pedidos do browser. Pode processar somente um pedido de cada vez, o que gera por sua vez o desempenho elevado. A classe handler implementa a interface IHttpHandler.

Para esta demonstração do artigo, nós exibiremos a imagem no controle GridView junto com os dados que nós armazenamos na tabela. Estão aqui as etapas requeridas para realizar isto:

1. Criar um arquivo Handler.ashx para executar a recuperação da imagem. Esta página de Handler.ashx conterá somente um método chamado ProcessRequest. Este método retornará dados binários ao pedido entrante. Neste método, nós faremos o processo normal e o retorno da recuperação de dados somente o campo de Image_Content como bytes do array.

Código de exemplo abaixo:
public void ProcessRequest (HttpContext context)
{
SqlConnection myConnection = new SqlConnection(“YourConnectionString”);
myConnection.Open();
string sql = "Select Image_Content from ImageGallery where Img_Id=@ImageId";
SqlCommand cmd = new SqlCommand(sql, myConnection);
cmd.Parameters.Add("@ImageId", SqlDbType.Int).Value = context.Request.QueryString["id"];
cmd.Prepare();
SqlDataReader dr = cmd.ExecuteReader();
dr.Read();
context.Response.ContentType = dr["Image_Type"].ToString();
context.Response.BinaryWrite((byte[])dr["Image_Content"]);
}

2. Colocar um controle GridView na página do aspx, com a uma coluna TemplateField, adicionar um controle de imagem na seção de ItemTemplate do TemplateField. Especificar a propriedade de ImageUrl como:
<asp:TemplateField>
<ItemTemplate>
<asp:Image ID="Image1" runat="server" ImageUrl='<%# "Handler.ashx?id=" + Eval("Img_Id") %>' />
</ItemTemplate>
</asp:TemplateField>
3. Agora nós podemos ligar o controle de GridView para exibir todos os registros na tabela:
GridView1.DataSource = FetchAllImagesInfo();
GridView1.DataBind ();

Antes que você ligue o GridView, você deve escrever o método de FetchAllImagesInfo para retornar todos os registros com os dados da imagem da tabela e então você tem que carregar as imagens no controle de GridView. Apenas isto. Quando você rodar seu projeto, você verá as imagens sendo carregadas no controle GridView.

public DataTable FetchAllImagesInfo())
{
string sql = "Select * from ImageGallery";
SqlDataAdapter da = new SqlDataAdapter(sql, "Your Connection String");
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
}

Esta é uma explanação muito simples sobre armazenar imagens na base de dados e para recuperá-las afim de exibí-las na Web page.

Para ver nossa aplicação de amostra, clique aqui.

quarta-feira, 23 de maio de 2007

Medindo intervalos de tempo no C#

O C# trouxe grandes facilidades no tratamento de datas e horas. Calcular a diferença entre dois tempos ficou fácil e preciso.

Neste artigo vou mostrar como calcular a diferença entre tempos usando os métodos e classes disponíveis no C#

Um exemplo prático irá esclarecer melhor. Vou calcular a diferença entre dois eventos.

Crie um novo projeto no C# e no formulário padrão coloque um botão de comando com o texto Iniciar e uma label com a propriedade Text vazia.

Vai funcionar assim :

  • Quando o usuário clicar no botão Iniciar iremos definir as variáveis do tipo DateTime para calcular a diferença entre os tempos:
    • t_inicio - receberá o valor do tempo quando o evento iniciar
    • t_fim - receberá o valor do tempo no fim do evento
    • t_diferenca - receberá a diferença calculada entre os tempos
  • Após clicar no botão o texto será alterado para - Parar -
  • Quando o usuário clicar em - Parar - o evento será encerrado e a diferença entre os tempos calculada e exibida.

O código associado ao evento Click do botão - btnMedir - é dado a seguir:

{
DateTime t_inicio;
DateTime t_fim;
TimeSpan t_diferenca;

if (btnMedir.Text == "Iniciar" )
{
lblDiferenca.Text = "";
t_inicio = DateTime.Now;
btnMedir.Text = "Parar";
}
else
{
t_fim = DateTime.Now;
t_diferenca = t_fim.Subtract(t_inicio);
lblDiferenca.Text = t_diferenca.TotalSeconds.ToString("0.000000") + " segundos";
btnMedir.Text = "Iniciar";
}
}

A mágica está na classe TimeSpan usada e no método Subtract usado para calcular a diferença entre os tempos.
Note que para expressar a diferença em segundos estou usando a propriedade TotalSeconds.

A classe TimeSpan representa um intervalo de tempo . O valor é medido em números de ticks contido em uma instância e pode variar de Int64.MinValue a Int64.MaxValue .(Um tick é a menor unidade de tempo que pode ser definida e é igual a 100 nano segundos).

Podemos representar um TimeSpan como uma string no formato "[-]d.hh:mm:ss.ff" onde "-" é um sinal opcional para valores negativos.

Os principais métodos e propriedades de TimeSpan são :

Propriedades Públicas

Days Obtêm o número total de dias representado pela instância
Hours Obtêm o número total de horas representado pela instância.
Milliseconds Obtêm o número total de milliseconds representado pela instância.
Minutes Obtêm o número total de minutos representado pela instância.
Seconds Obtêm o número total de segundos representado pela instância.
Ticks Obtêm o valor da instância expressa em ticks.
TotalDays Obtêm o valor da instância expressa em dias totais e fracionários.
TotalHours Obtêm o valor da instância expressa em horas totais e fracionárias.
TotalMilliseconds Obtêm o valor da instância expressa em milisegundos totais e não inteiros.
TotalMinutes Obtêm o valor da instância expressa em minutos totais e não inteiros.
TotalSeconds Obtêm o valor da instância expressa em segundos totais e não inteiros

Métodos Públicos

Add Incluir um TimeSpan especifico na instância.
Compare Compara dois valores de TimeSpan e retorna um inteiro que indica seu relacionamento.
Duration Retorna o TimeSpan cujo valor é o valor absoluto da instância.
Equals Overloaded. Overridden. Retorna um valor que indica se duas instâncias de TimeSpan são iguais.
Subtract Subtrai o valor definido de TimeSpan de sua instância.
ToString Overridden. Retorna uma representação em string de um valor da instância.

terça-feira, 17 de abril de 2007

INFO Online: Silverlight vem para brigar com Flash

A plataforma Silverlight vem para concorrer com o Flash na área de RIAs (Rich Internet Applications).

A tecnologia foi demonstrada pela Microsoft na NAB 2007, evento de telecomunicações organizado pela NAB (National Association of Broadcasters), entidade que representa os grandes conglomerados de mídia dos Estados Unidos.

A Silverlight é o novo nome do WPF/E (Windows Presentation Foundation Everywhere), plataforma da Microsoft para criação de aplicativos multimídia para internet. Espera-se que a Silverlight seja um concorrente direto do Flash, da Adobe, atualmente a alternativa mais popular para a construção de aplicativos multimídia para a web.

Do lado do usuário, a plataforma Silverlight consiste basicamente de um plug-in para navegadores. Ele está disponível atualmente para Windows e Macintosh e é necessário para que se tenha acesso a conteúdos produzidos para Silverlight. Por enquanto, não há versão para Linux.

Do lado do desenvolvedor, a Silverlight é um SDK (Software Development Kit) com bibliotecas, documentação, exemplos de código e ferramentas para montagem de aplicações que combinem gráficos vetoriais, animação, vídeo e áudio, entre outros elementos. Para manipular esses componentes, pode-se usar Ajax e XAML (linguagem baseada em XML adotada pela Microsoft). Os componentes de desenvolvimento estão disponíveis apenas para a plataforma Windows.

Tanto o plug-in quanto o SDK ainda estão em fase CTE (Community Technology Preview), um estágio inicial de desenvolvimento. Mas usuários mais curiosos já podem fazer o download (plug-in e SDK).

Saiba mais (info.abril.com.br)

INFO Online: Adobe anuncia player de vídeo

A Adobe anunciou hoje um player de vídeo para desktops, que executará arquivos do padrão Flash Video.

O Adobe Media Player permitirá que usuários assinem canais de vídeo por meio de RSS. Ainda não há uma data marcada para disponibilidade do software. Mas a empresa diz que ele será lançado nos próximos meses, em regime de download gratuito.

Um recurso importante para os produtores de vídeo é o suporte a tecnologias de proteção contra cópias ilegais. O DRM da Adobe poderá ser aplicado a arquivos de Flash Video.

Saiba mais (info.abril.com.br)

quinta-feira, 22 de março de 2007

How do I send out simple debug messages to help with my debugging?

How do I send out simple debug messages to help with my debugging?

(Clique aqui para ler em Português )

Visual Studio offers tons of useful debugging features and allows you to step through your code line-by-line. However, there are times when you don’t want to step through your application, but want to make it output simple text strings with variable values, etc.

Enter the System.Diagnostics.Debug class and its Write* methods. By using the Debug class, you can output messages similarly to the way the Win32 API function OutputDebugString. However, the beauty of the Debug class is that when you build your application using the default Release configuration in Visual Studio, no code lines are generated for your Debug.Write* class. This means there’s no performance penalty for using the Debug class in release code.

To use the Debug class, simply add the “using System.Diagnostics;” statement to your C# code file, and call Debug.Write:

Debug.Write("Hello, Debugger!");

In addition to Write, you have the possibility to call WriteIf, WriteLine and WriteLineIf. For example:

bool @this = true;
bool that = false;
Debug.WriteLineIf(@this || that, "A conditional Hello!");

When you are debugging your application under the Visual Studio debugger, all the messages that are sent out by your Write method calls end up in the Output window (View / Output menu command or Ctrl+W,O on the keyboard). However, if you are running your application outside the debugger (say, by starting it from Windows Explorer), you can still view the messages using tools like DebugView from Sysinternals.

Remember, if you build your application using the default Release configuration, even DebugView won’t show your messages because the Debug.Write* calls are eliminated altogether. You can also control code generation by defining the DEBUG conditional directive.

Tip: The .NET debugging/tracing architecture also allows you to redirect debugging messages to different destinations, such as text files. See the help topic “Trace Listeners” for more information.
Original
FAQ.

quinta-feira, 15 de março de 2007

Scroll ASP.NET Panel to bottom

Code Behind:
System.Web.UI.ScriptManager.RegisterStartupScript(Panel1, typeof(Panel), "scrollPanel", "scrollPanel();", true);

.aspx page

<script type="text/javascript">
function scrollPanel()
{
var panel = document.getElementById('<%=Panel1.ClientID%>');
panel.scrollTop = (panel.scrollHeight * 2);
}
</script>
you need to change the Panel1.ClientID to your panel.uniqueid.


Remember a Div's Scroll Position

A person asked the question on how to remember a div's scroll position on the page when the comes back to the page. It is rather easy to do and it involves a session cookie to remember the position. Yeah, the cookie part could be done better so do not comment on that! I went the easy route!

<html>
<head>
<title>Fun Scroll</title>
<style type="text/css">
#divTest{width:150px;height:200px;overflow:auto}
</style>
<script type="text/javascript">
window.onload = function(){
var strCook = document.cookie;
if(strCook.indexOf("!~")!=0){
var intS = strCook.indexOf("!~");
var intE = strCook.indexOf("~!");
var strPos = strCook.substring(intS+2,intE);
document.getElementById("divTest").scrollTop = strPos;
}
}
function SetDivPosition(){
var intY = document.getElementById("divTest").scrollTop;
document.title = intY;
document.cookie = "yPos=!~" + intY + "~!";
}
</script>
</head>
<body>
<div id="divTest" onscroll="SetDivPosition()">
1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>
1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>
1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>
1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>
ERIC<br/>
1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>
1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>
1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>
1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>
</div>
</body>
</html>
Hope it helps,
Erick Almeida

terça-feira, 27 de fevereiro de 2007

Conhecendo C# - Tipos - Parte 6

Conhecendo C# - Tipos - Parte 6
Boxing e Unboxing

Diferentemente de algumas linguagens orientada à objetos, o C# não exige um wrapper(empacotador) para manipular objetos e tipos, uma técnica muito mais poderosa é utilizada neste caso boxing e unboxing.

Boxing é a conversão de um tipo valor para um tipo referência e unboxing é o processo contrário desta conversão, ou seja extrai-se o conteúdo do tipo valor de um tipo referência herdado de System.ValueType. Somente conversões explícitas são suportadas para unboxing.

//Boxing
int x = 12345;
object o = x;

//Unboxing
x = (int)o;


Os tipos de dados herdados por System.ValueTypes são alocados em stack, por serem implementados como estrutura(struct), vide documentação de System.Int32 no .NET Framework SDK, por exemplo. Quando uma variável do tipo valor é utilizada, apenas seu contéudo é alocado em memória, no entanto se essa variável sofrer uma operação de boxing, seu valor será copiado para a heap e será acrescentado o overhead(excesso) do objeto System.ValueTypes(objeto herdado de System.Object, raíz de todos objetos do .NET Framework). A figura 4 exibe o estado do exemplo anterior que manipula um inteiro nas duas formas: boxing e unboxing.


Figura 4: Representação em memória de uma variável int nas formas boxing e unboxing

O que deve ficar claro no processo de conversão, é que o boxing pode ser tratado automáticamente, ou seja implícito, por exemplo para um inteiro(int) tornar-se um objeto(object) poderemos encontrar object o = 12345, neste caso o valor 12345 é tratado como inteiro(int). No entanto na forma unboxing, o tratamento explícito é requerido int x = (int)o, assumindo que o representa um object. Se a partir da forma boxing de um valor, através de conversão explícita, deseja-se obter a forma unboxing do mesmo, o cast no processo de unboxing deverá ser coerente com o tipo específicado, caso contrário um excessão InvalidCastException será disparada, isto também é válido para casts inconsistenes. O código abaixo demonstra isso:

long l = 12345;
object o = (long)l;

//Unboxing inconsistente
int i = (int)o; //excessão InvalidCastException

Segue a correção para o exemplo acima:

long l = 12345;
object o = (long)l;

//Unboxing consistente
int i = (int)(long)o;

Uma outra forma de utilizar as conversões é atráves da operação através de seus membros, ou seja, a partir de um conteúdo ou de uma variável é possível especificar a função ou método de conversão desejado. Se uma variável ou valor é de um tipo determinado, por exemplo, de um tipo int é correto utilizar i.ToInt64() ou 12345.ToInt64() para obter-se um valor do tipo long. O código anterior pode ser reescrito para:

object o = 12345.ToInt64(); //Valor tratado na forma boxing
//Unboxing consistente
int i = (int)(long)o;

De acordo com documentação do .NET Framework, se utilizarmos o método WriteLine da classe Console com uma string formatadora e vários tipos de dados, esses tipos serão tratados como um vetor(array) de objetos, conforme figura 5. Então quantos boxings serão executados na linha abaixo?

long l = 1000;
int i = 500;
Console.WriteLine(“{0} {1} {2} {3} {4} {5}”,l,i,i,l,l,i);

Figura 5: Uma das possibilidades do método WriteLine da classe Console

Seriam necessários 6 boxings para última linha, um para cada variável a ser tratada como objeto. O processo de boxing consome memória e tempo de execução da CPU, portanto o código acima é eficientemente reescrito para:

long l = 1000;
int i = 500;
object ol = l;
object oi = i;
Console.WriteLine(“{0} {1} {2} {3} {4} {5}”,ol,oi,oi,ol,ol,oi);

Neste caso o número de boxings é reduzido 2. Este tipo de cuidado sempre deverá ser tomado para a obtenção da melhor performance do código, resultando menos tempo de processamento e recursos consumidos.

Ir para o índice do Manual.
Próximo artigo: .

Conhecendo C# - Tipos - Parte 5

Conhecendo C# - Tipos - Parte 5
Estrutura(Struct) e Classe(Class)

Em C#, uma estrutura(struct) é sempre tratado como tipo valor, enquanto uma classe(class) é sempre tratado como tipo referência. Ambos são parecidos, suportam construtores(constructors), constantes(constants), campos(fields), métodos(methods), propriedades(properties), indexadores(indexers), operadores(operators) e tipos aninhados(nested types). Mas as estruturas não têm suporte a recursos relacionados ponteiros, ou melhor referências, tais como membros virtuais, construtores parametrizados, ponteiro this e membros abstratos.

using System;
//Classe
public class MyClassRect{
//Campos
public uint x, y;

//Calculo da área do retângulo
public ulong Area(){ return x*y; }
}

//Estrutura
public struct MyStructRect{
//Campos
public uint x, y;

//Calculo da área do retângulo
public ulong Area(){ return x*y; }
}

class MainClass{
public static void Main(){

MyClassRect cl = new MyClassRect(); //alocado na heap
MyStructRect st; //alocado na stack

cl.x = 10;
cl.y = 5;

st.x = 10;
st.y = 5;

Console.WriteLine("Classe - {0} m X {1} m = {2} m²" ,cl.x,cl.y,cl.Area());
Console.WriteLine("Estrutura - {0} m X {1} m = {2} m²",st.x,st.y,st.Area());

}

Para compilar o exemplo acima, no prompt, digite csc Class_Struct.cs. Execute o programa digitando Class_Struct. A Figura 3, mostra compilação e execução da aplicação em C#.


Figura
3: Compilação e Execução do exemplo Class_Struct

Ir para o índice do Manual.
Próximo artigo:
.

Neobux