Fórum Duvidas Relativo á aula XI do curso #5863
20/05/2009
Olá Fabio Galante - Boa Tarde
Como eu não estou recebendo as categorias em produtos via webusercontrol Menu.asxc e sim via dropdownlist dentro da pagina de Produtos do meu front end gostaria de saber como usar corretamente a diretiva do CacheDependency já que a coloquei desta forma direto na pagina, já que não usarei o controle mas o dropdownlist e deu o erro citado mais abaixo
Aqui o Source da Pagina produtos.aspx do frontend
<%@ Page Language="C#" MasterPageFile="~/Home.master" AutoEventWireup="true" CodeFile="produtos.aspx.cs" Inherits="produtos" Title="Untitled Page" ViewStateEncryptionMode="Always" EnableViewStateMac="true" ValidateRequest="true" %>
<%@ OutputCache Duration="99999" Shared="true" VaryByParam="CategoryID" SqlDependency="WebProdutos:dev_Categories" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentCenter" Runat="Server">
<asp:DropDownList ID="ddlCategorias" runat="server" DataSourceID="dsCategory"
DataTextField="Title" DataValueField="CategoryID" AutoPostBack="True">
</asp:DropDownList>
<asp:ObjectDataSource ID="dsCategory" runat="server"
OldValuesParameterFormatString="original_" SelectMethod="SelectCategory"
TypeName="DevMedia.ECommerce.Category"></asp:ObjectDataSource>
</asp:Content>
Aqui o Erro apresentado ao executar a webapplication no VS2008
Error 13 A diretiva 'outputcache' não oferece suporte para o atributo 'shared' em uma página. D:\MEUSASPNETWEBSITES\VS2008\Store\produtos.aspx 3
Aqui a config de meu webconfig
<connectionStrings>
<add name="StoreString" connectionString="Data Source=LUIZVIDEO\SQLEXPRESS;Initial Catalog=WebProdutos;Persist Security Info=True;User ID=userWebProdutos;Password=rolu27;" providerName="System.Data.SqlClient"/>
<remove name="LocalSqlServer"/>
<add name="LocalSqlServer" connectionString="Data Source=LUIZVIDEO\SQLEXPRESS;Initial Catalog=WebProdutos;Persist Security Info=True;User ID=userWebProdutos;Password=rolu27;" providerName="System.Data.SqlClient"/>
<!--<add name="StoreString" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\DevStore.mdf;Integrated Security=True;User Instance=True" providerName="System.Data.SqlClient"/>-->
<add connectionString="server=mysqlserver.com;database=mysqldatabase;user id=mysqlid;pwd=mysqlpwd" name="SimpleProviderConnectionString" providerName="MySql.Data.MySqlClient"/>
</connectionStrings>
<system.web>
<!-- INCIO CONFIGS MYSQLSITEMAPPROVIDER -->
<roleManager enabled="true"/>
<authentication mode="Forms"/>
<caching>
<sqlCacheDependency enabled="true" pollTime="15000">
<databases>
<add name="WebProdutos" connectionStringName="StoreString"/>
</databases>
</sqlCacheDependency>
</caching>
<siteMap defaultProvider="siteMapProvider" enabled="true">
<providers>
<clear/>
<add name="siteMapProvider" type="Simple.Providers.MySQL.MysqlSiteMapProvider" connectionStringName="SimpleProviderConnectionString" applicationName="WebProdutos" description="MySQL site map provider" securityTrimmingEnabled="true"/>
</providers>
</siteMap>
<!-- FIM CONFIGS MYSQL SITEMAPPROVIDER -->
Aqui as minhas SP atuais
SP - SelectAllCategory
ALTER PROCEDURE [dbo].[dev_SelectAllCategory]
(
@Grupo VarChar(150)
)
AS SELECT CategoryID, Title FROM dbo.dev_Categories Where Grupo = @Grupo
ORDER BY Title
SET NOCOUNT ON
RETURN
SP CategorySelect
ALTER PROCEDURE [dbo].[dev_CategorySelect]
(
@Id Int
)
AS
SELECT
CategoryId,
Grupo,
Title
FROM
dev_Categories
WHERE
CategoryId = @Id
Que tem a haver com a pagina products ou produtos.aspx do frontend
E aqui a minha classe atual Category.cs
using System;
using System.Data;
using System.Configuration;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
using System.Web.Configuration;
namespace DevMedia.ECommerce
{
/// <summary>
/// Representa a Categoria de um Produto ou Servio
/// e contem mtodos para trabalhar com a Categoria
/// </summary>
[System.ComponentModel.DataObject]
public class Category
{
private static readonly string _connectionString;
private int _id;
//private string _grupo;
private string _title;
public int CategoryID
{
get { return _id; }
set { _id = value; }
}
//public string Grupo
///{
//get { return _grupo; }
//set { _grupo = value; }
/// }
public string Title
{
get { return _title; }
set { _title = value; }
}
static Category()
{
_connectionString = WebConfigurationManager.ConnectionStrings["StoreString"].ConnectionString;
}
public Category(SqlDataReader reader)
{
_id = (int)reader["CategoryID"];
//_grupo = (string)reader["Grupo"];
_title = (string)reader["Title"];
}
/// <summary>
/// Seleciona Todas as Categorias do Banco de Dados
/// </summary>
/// <returns></returns>
[System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select,true)]
public static List<Category> SelectCategory()
{
string Grupo = HttpContext.Current.Request.QueryString["sessao"];
//Inicializar Comando
SqlConnection con = new SqlConnection(_connectionString);
SqlCommand cmd = new SqlCommand("dev_SelectAllCategory", con);
cmd.CommandType = CommandType.StoredProcedure;
//Initialize parameters
cmd.Parameters.AddWithValue("@Grupo", Grupo);
List<Category> results = new List<Category>();
using (con)
{
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
results.Add(new Category(reader));
}
con.Close();
return results;
}
}
/// <summary>
/// Seleciona Todas as Categorias do Banco de Dados
/// Baseado na SubSessao em Servios
/// </summary>
/// <returns></returns>
[System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select, false)]
public static List<Category> Services()
{
string Grupo = HttpContext.Current.Request.QueryString["subsessao"];
//Inicializar Comando
SqlConnection con = new SqlConnection(_connectionString);
SqlCommand cmd = new SqlCommand("dev_SelectAllCategory", con);
cmd.CommandType = CommandType.StoredProcedure;
//Initialize parameters
cmd.Parameters.AddWithValue("@Grupo", Grupo);
List<Category> results = new List<Category>();
using (con)
{
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
results.Add(new Category(reader));
}
con.Close();
return results;
}
}
/// <summary>
/// Seleciona uma Categoria por Category ID
/// </summary>
/// <param name="CategoryID"></param>
/// <returns></returns>
[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, false)]
public static Category SelecById(int CategoryID)
{
//Inicializar o Command
SqlConnection con = new SqlConnection(_connectionString);
SqlCommand cmd = new SqlCommand("dev_CategorySelect", con);
cmd.CommandType = CommandType.StoredProcedure;
//Inicializar Parameters p/ Evitar SqlInjection
cmd.Parameters.AddWithValue("@Id", CategoryID);
//Criar Variavel para Retorno de Resultados
Category result = null;
using (con)
{
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.Read())
result = new Category(reader);
}
con.Close();
return result;
}//<summary>
//Create a new category
//</summary>
//<param name="parentId"></param>
[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Insert, true)]
public static void Insert(string grupo, string title)
{
//Initialize command
SqlConnection con = new SqlConnection(_connectionString);
SqlCommand cmd = new SqlCommand("dev_CategoryInsert ", con);
cmd.CommandType = CommandType.StoredProcedure;
//Initialize parameters
cmd.Parameters.AddWithValue("@Grupo", grupo);
cmd.Parameters.AddWithValue("@Title", title);
using (con)
{
con.Open();
cmd.ExecuteNonQuery();
}
con.Close();
}
/// <summary>
/// Update numa CategoryID Existente
/// </summary>
/// <param name="CategoryId"></param>
/// <param name="Title"></param>
[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Update, true)]
public static void Update(int CategoryId, string Title)
{
//Inicializar o Command
SqlConnection con = new SqlConnection(_connectionString);
SqlCommand cmd = new SqlCommand("dev_CategoryUpdate", con);
cmd.CommandType = CommandType.StoredProcedure;
//Inicializar Parameters p/ Evitar SqlInjection
cmd.Parameters.AddWithValue("@Id", CategoryId);
cmd.Parameters.AddWithValue("@Title", Title);
using (con)
{
con.Open();
cmd.ExecuteNonQuery();
}
con.Close();
} /// <summary>
/// Delete a category
/// </summary>
[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Delete, true)]
public static void DeleteCat(int CategoryId)
{
// Initialize command
SqlConnection con = new SqlConnection(_connectionString);
SqlCommand cmd = new SqlCommand("dev_CategoryDelete", con);
cmd.CommandType = CommandType.StoredProcedure;
// Initialize parameters
cmd.Parameters.AddWithValue("@CategoryId", CategoryId);
using (con)
{
con.Open();
cmd.ExecuteNonQuery();
}
}
}
}
Fico no aguardo e desde já agradeço para saber como eu teria que adaptar e resolver este erro da diretiva Shared na pagina produtos.aspx
Posts
Você assistiu a aula sobre Cache referente a este curso? Fez todos os procedimentos?
Olá Fabio Galante - Boa Tarde
Sim se não me engano é a aula 3 ou 4 que vc fala sobre isso fiz todos os Procedimentos, é que como eu quero adaptar o OUPTUT CACHE NA PAGINA produtos que está com objeto DropDownList para chamar categorias como abaixo
<%@ Page Language="C#" MasterPageFile="~/Home.master" AutoEventWireup="true" CodeFile="produtos.aspx.cs" Inherits="produtos" Title="Untitled Page" ViewStateEncryptionMode="Always" EnableViewStateMac="true" ValidateRequest="true" %>
<%@ OutputCache Duration="99999" VaryByParam="CategoryID" SqlDependency="WebProdutos:dev_Categories" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentCenter" Runat="Server">
<asp:DropDownList ID="ddlCategorias" runat="server" DataSourceID="dsCategory"
DataTextField="Title" DataValueField="CategoryID" AutoPostBack="True">
</asp:DropDownList>
<asp:ObjectDataSource ID="dsCategory" runat="server"
OldValuesParameterFormatString="original_" SelectMethod="SelectCategory"
TypeName="WebProdutos.ECommerce.Category"></asp:ObjectDataSource>
</asp:Content>
Estou usando o VS2008 com NETFRAMEWORK 3.5 e um aplicativo para verificação de Cache para versão express do SqlServer deste link
http://code.google.com/p/sqlexpressprofiler/downloads/list
No Visual Studio 2008 ele dá erro qdo coloco na pagina
<%@ OutputCache Duration="99999" Shared="true" VaryByParam="CategoryID" SqlDependency="WebProdutos:dev_Categories" %>
E no DropDownList das categorias conforme source.aspx ácima em modo de execução, por exemplo qdo seleciono o segundo iten do DropDownList que está na base, mesmo que na sequência eu selecione uma outra categoria que não á do primeiro selecionado ele sempre retorna para o primeiro no DropDownList
Por exemplo
Eu seleciono - pela primeira vêz - Informática
na segunda vêz qdo seleciono eletrodomésticos ele retorna para Informática (ou o ítem selecionado pela primeira vêz) gostaria de saber o pq acontece isto
Observação deste modo abaixo e no aplicativo de profile citado ácima ele reconhece o cache profiling
<%@ OutputCache Duration="99999" VaryByParam="CategoryID" SqlDependency="WebProdutos:dev_Categories" %>
Fico no aguardo e desde já agradeço
Funciona destas duas formas
Qdo Habilitado o AutoPost Back do DropDownList como igual á True (somente sem o Cache)
Qdo Desabilitado o AutoPost Back do DropDownList como igual á True (com o Cache)
como coloco o OutputCache na pagina do Vs2008 e uso o objeto DropDownlist para selecionar as subcategorias vinda da base para futuramente chamar os produtos qdo eu chegar na aula certa, não haveria alguma propriedade dentro do OutputCache que resolve-se este problema lembrando que ele na pagina não reconhece a propriedade Shared=true
Fico no aguardo e desde já agradeço
Você pode fazer via código, veja um exemplo.
CACHE DATASET
protected void btnOK_Click( object sender, EventArgs e )
{
gvwProdutos.DataSource = RecuperaProdutos();
gvwProdutos.DataBind();
}
private DataTable RecuperaProdutos()
{
if ( Cache["produtos"] == null )
{
lblMensagem.Text = "Dados do Banco de dados";
return SelecionaProdutos();
}
else
{
lblMensagem.Text = "Dados do Cache";
return Cache["produtos"] as DataTable;
}
}
private DataTable SelecionaProdutos()
{
SqlConnection cnDados = new SqlConnection( @"Data Source=ANDRE_DESKTOP;Initial Catalog=dbDados;Integrated Security=True" );
SqlDataAdapter daProduto = new SqlDataAdapter( "SELECT * FROM TBPRODUTO ORDER BY DESCRICAO", cnDados );
DataTable dtProduto = new DataTable();
daProduto.Fill( dtProduto );
CacheProdutos( dtProduto );
return dtProduto;
}
private void CacheProdutos( DataTable dtProduto )
{
if ( Cache["produtos"] == null )
{
Cache.Insert( "produtos", dtProduto, null, DateTime.Now.AddSeconds( 10 ), TimeSpan.Zero );
}
}
Olá Fabio Galante mas no caso como ficaria o mesmo exemplo para o DropDownList que tem a haver com as Categorias
<%@ Page Language="C#" MasterPageFile="~/Home.master" AutoEventWireup="true" CodeFile="produtos.aspx.cs" Inherits="produtos" Title="Untitled Page" ViewStateEncryptionMode="Always" EnableViewStateMac="true" ValidateRequest="true" %>
<%@ OutputCache Duration="99999" VaryByParam="CategoryID" SqlDependency="DevMedia:dev_Categories" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentCenter" Runat="Server">
<asp:DropDownList ID="ddlCategorias" runat="server" DataSourceID="dsCategory"
DataTextField="Title" DataValueField="CategoryID" AutoPostBack="False">
</asp:DropDownList>
<asp:ObjectDataSource ID="dsCategory" runat="server"
OldValuesParameterFormatString="original_" SelectMethod="SelectCategory"
TypeName="DevMedia.ECommerce.Category"></asp:ObjectDataSource>
</asp:Content>
Fico no aguardo e desde já agradeço
Com o exemplo que te passei você não conseguiu implentar?
É que não entendi, o que vc me passou tem a haver com a table e classe products correto? como eu o faria na classe categoria que é aonde eu uso o dropdownlist como ti passei no source, é isso que não entendi o code que vc me passou tem a haver com a categorias ou products, pq o meu dropdownlist vem com os dados de categorias como vc pd vêr se precisar eu lhe passo um video que lhe farei até amanhã ok
Você recupera o ID da categoria no drop, e através deste ID recupera os produtos.
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">
</asp:DropDownList>
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
}
==================================================================
É
que não entendi, o que vc me passou tem a haver com a table e classe
products correto? como eu o faria na classe categoria que é aonde eu
uso o dropdownlist como ti passei no source, é isso que não entendi o
code que vc me passou tem a haver com a categorias ou products, pq o
meu dropdownlist vem com os dados de categorias como vc pd vêr se
precisar eu lhe passo um video que lhe farei até amanhã ok
Olá Fabio Galante
Duas duvidas
Primeiro - Referente ao Evento SelectIndexChanged que me passou o que coloco dentro deste evento
Segundo - Como eu disse qdo coloco o OutputCache e o Autopostback=true qdo no dropdownlist eu primeiro seleciono em modo de execução - o 2 item, na hora que vou selecionar outro item qq ele volta no 2 item de novo mostrado no dropdownlist, já qdo o coloco como Autopostback=false ai o Cache dependency funciona normalmente como o meu outputcache está na pagina não tem que mexer em nenhuma propriedade desta linha
<%@ OutputCache Duration="99999" VaryByParam="CategoryID" SqlDependency="DevMedia:dev_Categories" %>
ou com o codigo que vc me passou mesmo o drop em autopostback= true irá resolver
Fico no aguardo e desde já agradeço
Para simplificar vamos fazer tudo via código OK.
Não vou explicar utilizando ObjectDataSource.
Primeiro, o autopostback vai dar um post e trazer todos os produtos referente aquela categoria através do evnedo SelectIndexChand.
Para isso você precisa criar um método que receba o id da categoria e retorno os produtos, pode ser um DataTable.
Referente ao cache vamos simplicar, faça diferente, esqueça a diretiva abaixo.
<%@ OutputCache Duration="99999" VaryByParam="CategoryID" SqlDependency="DevMedia:dev_Categories" %>
Crie um método que te retorne um DataTable com as categoria e para popular o DropCategoria faça o seguinte. Veja abaixo como colocar o drop na cache.
// 1 - Carrega o Grid verificando se o DataTable esta no cache.
private void BindBancos()
{
//drpBanco.DataSource = RecuperaBancos();
//drpBanco.DataTextField = "BANCO";
//drpBanco.DataValueField = "BANCO";
//drpBanco.DataBind();
//drpBanco.Items.Insert(0, new ListItem(" --- SELECIONE --- ", "0"));
}
// 2 - Verifica se existe o cache e retorna, caso contrário retorna do banco
private DataTable RecuperaBancos()
{
return Cache["B"] == null ? dtBC() : Cache["B"] as DataTable;
}
//3 - Consulta no banco e inclui os dados no banco
private DataTable dtBC()
{
DataTable dtB = DespesasBusiness.ConsultarBancos();
CacheB(dtB);
return dtB;
}
//4 - Adiciona o DataTable o Cache
private void CacheB(DataTable dtB)
{
if (Cache["B"] == null)
{
Cache.Insert("B", dtB, null, DateTime.Now.AddMinutes(60), TimeSpan.Zero);
}
}
Espero ter ajudado
==================================================================
====================================================================
Olá Fabio Galante
Duas duvidas
Primeiro - Referente ao Evento SelectIndexChanged que me passou o que coloco dentro deste evento
Segundo - Como eu disse qdo coloco o OutputCache e o Autopostback=true qdo no dropdownlist eu primeiro seleciono em modo de execução - o 2 item, na hora que vou selecionar outro item qq ele volta no 2 item de novo mostrado no dropdownlist, já qdo o coloco como Autopostback=false ai o Cache dependency funciona normalmente como o meu outputcache está na pagina não tem que mexer em nenhuma propriedade desta linha
<%@ OutputCache Duration="99999" VaryByParam="CategoryID" SqlDependency="DevMedia:dev_Categories" %>
ou com o codigo que vc me passou mesmo o drop em autopostback= true irá resolver
Fico no aguardo e desde já agradeço
Luiz,
a resposta do consultor foi suficiente? Podemos encerrar o chamado?
Luiz,
por falta de retorno estamos mudando o status do seu chamado para concluído. caso tnha mais duvidas sobre o assunto aqui tratato, por favor, post aqi mesmo q o consultor voltará a lhe atender.
Olá Primeiramente como eu faria esse metodo do datatable baseado no category.cs para sêr aproveitado no metodo e drpBanco (seria o id do dropdownlist, ddlCategorias, de meu source mais abaixo)
// 1 - Carrega o Grid verificando se o DataTable esta no cache.
private void BindBancos()
{
//drpBanco.DataSource = RecuperaBancos();
//drpBanco.DataTextField = "BANCO";
//drpBanco.DataValueField = "BANCO";
//drpBanco.DataBind();
//drpBanco.Items.Insert(0, new ListItem(" --- SELECIONE --- ", "0"));
}
// 2 - Verifica se existe o cache e retorna, caso contrário retorna do banco
private DataTable RecuperaBancos()
{
return Cache["B"] == null ? dtBC() : Cache["B"] as DataTable;
}
//3 - Consulta no banco e inclui os dados no banco
private DataTable dtBC()
{
DataTable dtB = DespesasBusiness.ConsultarBancos();
CacheB(dtB);
return dtB;
}
//4 - Adiciona o DataTable o Cache
private void CacheB(DataTable dtB)
{
if (Cache["B"] == null)
{
Cache.Insert("B", dtB, null, DateTime.Now.AddMinutes(60), TimeSpan.Zero);
}
}
<%@ Page Language="C#" MasterPageFile="~/Home.master" AutoEventWireup="true" CodeFile="produtos.aspx.cs" Inherits="produtos" Title="Untitled Page" ViewStateEncryptionMode="Always" EnableViewStateMac="true" ValidateRequest="true" %>
<%@ OutputCache Duration="99999" VaryByParam="CategoryID" SqlDependency="WebProdutos:dev_Categories" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentCenter" Runat="Server">
<asp:DropDownList ID="ddlCategorias" runat="server" DataSourceID="dsCategory"
DataTextField="Title" DataValueField="CategoryID" AutoPostBack="False">
</asp:DropDownList>
<asp:ObjectDataSource ID="dsCategory" runat="server"
OldValuesParameterFormatString="original_" SelectMethod="SelectCategory"
TypeName="Devmedia.ECommerce.Category"></asp:ObjectDataSource>
</asp:Content>
Fico no aguardo e desde já agradeço
Luiz você diz o DataTable?
private DataTable SelecionaProdutos()
{
SqlConnection cnDados = new SqlConnection( @"Data Source=ANDRE_DESKTOP;Initial Catalog=dbDados;Integrated Security=True" );
SqlDataAdapter daProduto = new SqlDataAdapter( "SELECT * FROM TBPRODUTO ORDER BY DESCRICAO", cnDados );
DataTable dtProduto = new DataTable();
daProduto.Fill( dtProduto );
CacheProdutos( dtProduto );
return dtProduto;
}
[]'s