简体   繁体   English

如何捕获由.asmx文件中的RAISEERROR()触发的SQL存储过程错误?

[英]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.

相关问题 如何确定 SQL Server 存储过程参数是否具有默认值? - How can I determine if a SQL Server stored procedure parameter has a default? C#/DataTable/DataGrid/SQL - 如何从 DataGridView 将参数插入到存储过程中 - C#/DataTable/DataGrid/SQL - How can I insert Params into a stored procedure from DataGridView 我如何跳过将可选参数传递给Linq中的存储过程到SQL - how I can skip passing optional parameter to stored procedure in Linq to SQL Formview插入模板在.NET 2.0中运行存储过程后,如何捕获inputoutput参数值? - How do I capture inputoutput parameter value after a Formview Insert template runs stored procedure in .NET 2.0? 如何计算存储过程返回的行? - How can I count rows returned by the stored procedure? 如何将选择的存储过程映射到EF 3.5中的实体? - How can I map a select stored procedure to an entity in EF 3.5? 如何从存储过程检索表到数据表? - How can I retrieve a table from stored procedure to a datatable? 如何从LINQ-to-SQL或SQL Server中获取有关存储过程错误的完整错误信息? - How do you get full error information for a stored procedure error out of LINQ-to-SQL or SQL Server? 我可以在SQL Server Management Studio中执行我的存储过程,但是Webservice无法执行 - I can exec my stored procedure in SQL Server Management Studio but webservice can not 如何提高SQL Server存储过程的性能? - How to improve SQL Server stored procedure performance?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM