Comment puis-je capturer une erreur SQL procédure stockée déclenchée par raiseError () dans le fichier .asmx?
-
12-09-2019 - |
Question
Je suis très nouveau .NET. Tout ce que je l'ai fait jusqu'à présent est de mettre en œuvre des appels SQL procédure stockée comme WebServices en copiant et collant le code existant (comme indiqué par mon supérieur).
J'appelle des commandes via Database.ExecuteNonQuery()
. Dans la procédure stockée SQL, je l'exécution de contrôles de sécurité basés sur la loginid adoptée en (un utilisateur ne peut modifier les éléments dont ils sont le propriétaire). Si le contrôle de sécurité échoue, je fais appel raiseError () pour déclencher une erreur, mais mon fichier .asmx ne voit pas cela comme une exception, et sort 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");
}
}
My 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
La solution 2
Je mis à jour ma procédure stockée qui suit:
/* 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
Et je gère 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);
Autres conseils
Le problème est que la gravité de l'erreur trop bas. Gravités 1 -. 10 sont considérés comme des messages d'information et de ne pas casser l'écoulement d'une application C #
Une explication plus approfondie peut être trouvée dans un répondre de Remus Rusanu .