2009-07-09 3 views
0

Je suis très nouveau à .NET. Tout ce que j'ai fait jusqu'ici est d'implémenter des appels SQL Stored Procedure en tant que WebServices en copiant et en collant du code existant (comme demandé par mon supérieur).Comment puis-je capturer une erreur de procédure stockée SQL déclenchée par RAISEERROR() dans le fichier .asmx?

J'appelle certaines commandes via Database.ExecuteNonQuery(). Dans la procédure stockée SQL, j'effectue des contrôles de sécurité basés sur le LoginId transmis (un utilisateur ne peut modifier que les éléments dont il est le propriétaire). Si la vérification de sécurité échoue, j'appelle RAISEERROR() pour déclencher une erreur, mais mon fichier .asmx ne voit pas cela comme une exception, et quitte simplement la procédure stockée.

Mon fichier asmx:

[WebMethod] 
public XmlDocument UpdateSomeItem(Int32 ItemIdNmb, String Foo) 
{ 
    try 
    { 

     // Create the Database object, using the default database service. The 
     // default database service is determined through configuration. 
     Database db = DatabaseFactory.CreateDatabase(); 
     DbParameter param; 

     string sqlCommand = "updateSomeItem"; 
     DbCommand dbCommand = db.GetStoredProcCommand(sqlCommand); 

     db.AddInParameter(dbCommand, "ItemIdNmb", DbType.Int32, ItemIdNmb); 
     db.AddInParameter(dbCommand, "Foo", DbType.String, Foo); 
     db.AddInParameter(dbCommand, "UpdateLoginIdNmb", DbType.Int32, SessionLoginIdNmb); 

     #region Return Parameter 
     param = dbCommand.CreateParameter(); 
     param.ParameterName = "Return"; 
     param.Direction = ParameterDirection.ReturnValue; 
     param.DbType = DbType.Int32; 

     dbCommand.Parameters.Add(param); 
     #endregion 

     // Execute the Command 
     db.ExecuteNonQuery(dbCommand); 

     myDataSet = new DataSet(); 

     myDataSet.DataSetName = "DataSet"; 
     myDataSet.Tables.Add(errorDataTable); 

     statusDataRow["Status"] = "Success"; 
     statusDataTable.Rows.Add(statusDataRow); 
     myDataSet.Tables.Add(statusDataTable); 

     returncodeDataRow["ReturnCode"] = dbCommand.Parameters["Return"].Value; 
     returncodeDataTable.Rows.Add(returncodeDataRow); 
     myDataSet.Tables.Add(returncodeDataTable); 

     xmlReturnDoc.LoadXml(myDataSet.GetXml()); 

     return xmlReturnDoc; 
    } 
    // THIS IS WHERE I WANT MY RAISE ERROR TO GO 
    catch (Exception e) 
    { 
     return ReturnClientError(e, "someerror"); 
    } 
} 

Mon SQL procédure stockée:

CREATE PROCEDURE updateSomeItem 
(
    @ItemIdNmb    INT, 
    @Foo     VARCHAR(100), 
    @UpdateLoginIdNmb  INT 
) 

AS 

SET NOCOUNT ON 

/* If the user performing the action did not create the Item in question, 
    raise an error. */ 
IF NOT EXISTS 
    (
    SELECT 1 
    FROM Items 
    WHERE IdNmb = @ItemIdNmb 
     AND LoginIdNmb = @UpdateLoginIdNmb 
    ) 
    RAISERROR (
     'User action not allowed - User is not the owner of the specified Item', 
     10, 
     1) 

UPDATE Items 
SET Foo = @Foo 
WHERE IdNmb = @ItemIdNmb 

RETURN 0 

SET NOCOUNT OFF 
GO 

Répondre

1

Je mis à jour ma procédure stockée avec les éléments suivants:

/* If the user performing the action did not create the Item in question, 
    return a code other than 0. */ 
IF NOT EXISTS 
    (
    SELECT 1 
    FROM Items 
    WHERE IdNmb = @ItemIdNmb 
     AND LoginIdNmb = @UpdateLoginIdNmb 
    ) 
    RETURN 1 

Je poignée dans mon dossier .asmx comme ceci:

int returnValue = (int)dbCommand.Parameters["Return"].Value; 

if (returnValue == 0) 
    statusDataRow["Status"] = "Success"; 
/* Stored Procedure will return a value of "1" if the user is 
    attempting to update an Item that they do not own. */ 
else 
    statusDataRow["Status"] = "Error"; 

statusDataTable.Rows.Add(statusDataRow); 
myDataSet.Tables.Add(statusDataTable); 

returncodeDataRow["ReturnCode"] = dbCommand.Parameters["Return"].Value; 
returncodeDataTable.Rows.Add(returncodeDataRow); 
myDataSet.Tables.Add(returncodeDataTable); 
2

Le problème est que la gravité de l'erreur trop bas. Les sévérités 1 à 10 sont traitées comme des messages d'information et ne perturbent pas le flux d'une application C#. Une explication plus complète peut être trouvée dans un answer de Remus Rusanu.

+0

Merci @ahsteele. C'est logique. J'ai changé ma logique pour retourner un code différent dans la condition que j'ai décrite, et pour gérer le code de retour dans mon C# (voir ci-dessous). –

Questions connexes