[英]How can I capture a SQL Stored Procedure Error triggered by RAISEERROR() in .asmx file?
I'm very new to .NET. 我很新的.NET。 All I've done so far is implement some SQL Stored Procedure calls as WebServices by copying and pasting existing code (as instructed by my superior). 到目前为止,我所做的就是通过复制和粘贴现有代码(如上司所言)将一些SQL存储过程调用作为WebServices实现。
I am calling some commands via Database.ExecuteNonQuery()
. 我通过Database.ExecuteNonQuery()
调用了一些命令。 In the SQL Stored Procedure, I am performing some security checks based on the LoginId passed in (a user can only edit items of which they are the owner). 在SQL存储过程中,我将根据传入的LoginId进行一些安全检查(用户只能编辑其所有者的项目)。 If the security check fails, I am calling RAISEERROR() to trigger an error, but my .asmx file is not seeing this as an exception, and simply exits the Stored Procedure. 如果安全检查失败,我将调用RAISEERROR()来触发错误,但是我的.asmx文件没有将此视为异常,而只是退出了存储过程。
My asmx file: 我的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 Stored Procedure: 我的SQL存储过程:
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
The problem is that the Error Severity it too low. 问题是错误严重性太低。 Severities 1 - 10 are treated as information messages and do not break the flow of a C# app. 严重级别1-10被视为信息消息,并且不会中断C#应用程序的流程。
A more thorough explanation can be found in an answer from Remus Rusanu . 在Remus Rusanu的回答中可以找到更详尽的解释。
I updated my Stored Procedure with the following: 我使用以下内容更新了存储过程:
/* 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
And I handle in my .asmx file like this: 我在我的.asmx文件中处理如下:
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);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.