Tratamento de erros via banco de dados

15/07/2009

No meu projeto (asp.net em C#) estou utilizando basicamente datasources e formviews com banco de dados SQL Server em uma masterpage com scriptmanager e updatepanel.
Gostaria de saber como é possível interpretar erros vindos do banco de dados e mostrar ao usuário de forma amigável e também executar códigos alternativos quando ocorrer os mesmos.
Alguns tipos de erros que gostaria de tratar são: duplicidade de registro, erro ao excluir em relacionamentos, exceção vinda de procedures.
Se possível exemplos bem detalhados, pois estou iniciando...


Obrigado!
Valter Ferreira

Valter Ferreira

Curtidas 0

Respostas

Fabio Mans

Fabio Mans

15/07/2009

Olá Valter, existe algumas formas de você tratar o erro, mas sempre com try/catch.


Neste primeiro exemplo eu deixo dar o erro, pego um pedaço frase do erro e procuro na exceção através do Contais.

 try
            {
                string name = txtName.Text;
                string password = txtPassword.Text;
                string email = txtEmail.Text;

                UsersBriefCase.Create(name, password, email);
                authenticate(name, email, password);
            }
            catch (SqlException ex)
            {
                if (ex.Message.Contains("IX_UserName"))
                    lblMsg.Text = "Selecione outro login, já existe um outro como mesmo nome.";
                else if (ex.Message.Contains("IX_Email"))
                    lblMsg.Text = "Selecione outro email, já existe um cadastro com este email.";
                else
                    lblMsg.Text = ex.Message;
            }




Uma outra maneira é tratar na proc, veja o exemplo.


CREATE PROCEDURE [Estetica_CadastrarPacientes]

(
             @RG               [nvarchar](50),
             @Paciente       [nvarchar](50),
             @Telefone       [nvarchar](15),
             @Celular         [nvarchar](15),
             @EMail           [nvarchar](25)
)

 AS

IF NOT EXISTS(SELECT Paciente FROM  [Estetica].[dbo].[T_Pacientes]  WHERE Paciente = @Paciente)
BEGIN
INSERT INTO [Estetica].[dbo].[T_Pacientes]
             ( [RG],
             [Paciente],
             [Telefone],
             [Celular],
             [EMail])
 

VALUES

            ( @RG,
             @Paciente,
             @Telefone,
             @Celular,
             @EMail)
END
ELSE
BEGIN
RAISERROR ('Paciente já cadastro',11,127)
END
GO


No try catch vai ocorrer um erro, que será a mensagem Paciente já cadastrado.


Um outra opção é você tratar dependendo da Exception, no exemplo abaixo o usuário está tentando ler uma pasta que não tem permissão, ocorreu o erro eu percebi que é através da IOException assim eu personalizei a mensagem sem permissão na pasta.


catch (System.IO.IOException ex)
        {
            Label1.Text = "Sem permissão na pasta" + ex.Message;

        }


Este outro exemplo é uma e exceção SQL


 catch (SqlException ex)
        {
            lblMsg.Text = "Erro no banco de dados: " + ex.Message;
        }


Para cada situação você vai ter uma mensagem diferente, com os exemplos acima você consegue facilmente personalizar suas mensagens, basta estudar os erros que ocorrem na sua aplicação e aplicar a mensagem no catch.


Espero ter ajudado.


Fabio
GOSTEI 0
Devmedia

Devmedia

15/07/2009

Valter,
a resposta do consultor conseguiu resolver suas dúvidas? Podemos encerrar o chamado?

GOSTEI 0
Valter Ferreira

Valter Ferreira

15/07/2009

A utilização do Try/Catch já era do meu conhecimento mas daria muito trabalho de implementar uma vez que já tenho muitas telas prontas e eu teria que adicionar o Try/Catch em cada uma delas.

Gostaria de solucionar a personalização do retorno de erros de banco de dados como duplicidade, relacionamentos, etc. de forma mais "global".

Vi uma vez, um outro projeto feito em VB, onde uma tela default.aspx com ScriptManager e UpdatePanel, chamava outras telas do tipo "user control", onde cada uma tinha um gridview com inserção, edição e exclusão. No SOURCE da default.aspx possuia um evento chamado "protected void ScriptManager1_AsyncPostBackError", neste evento era personalizado todos os erros de banco de dados, assim cada tela de User Control não tinha necessidade da utilização de Try/Catch.

Neste meu projeto atual, desejo fazer o mesmo. Apesar de não estar usando User Control, todas as minhas telas são chamadas por uma MasterPage e em minha MasterPage utilizo ScriptManager e UpdatePanel.

Não tenho experiência em utilizar AsyncPostBackError e gostaria de saber como utilizá-lo ou gostaria de uma forma mais "global" de personalizar os erros de banco de dados sem ter que necessariamente programar em todas as telas.


Fico no aguardo.

Obrigado.
GOSTEI 0
Fabio Mans

Fabio Mans

15/07/2009

A sim, só que o seu chamado não falava sobre isso.

O que você tem que fazer é o seguinte.


protected void ScriptManager1_AsyncPostBackError(object sender, AsyncPostBackErrorEventArgs e)
    {
        ScriptManager1.AsyncPostBackErrorMessage = e.Exception.Message+e.Exception.StackTrace ;
    }

aspx:<asp:ScriptManager ID="ScriptManager1" runat="server"
            OnAsyncPostBackError="ScriptManager1_AsyncPostBackError">
            </asp:ScriptManager> 

Fabio

GOSTEI 0
Fabio Mans

Fabio Mans

15/07/2009

Veja este link, acredito que sem alterar nada no código vai ser complicado.


http://msdn.microsoft.com/pt-br/library/bb398934.aspx#Mtps_DropDownFilterText

Fabio
GOSTEI 0
Devmedia

Devmedia

15/07/2009

Valter,
a resposta do consultor foi suficiente? Podemos encerrar o chamado?
GOSTEI 0
Devmedia

Devmedia

15/07/2009

por falta de retorno estamos concluindo o chamado. Se ainda as dúvidas sobre esse assunto persistirem, por favor, volte a postar aqui mesmo que o consultor voltará a lhe atender.
GOSTEI 0
POSTAR