2009-07-09 1 views
0

私は非常に .netの新機能です。私がこれまで行ってきたことは、既存のコードをコピーして貼り付けることによって(私の上司が指示したように)WebサービスとしてSQLストアドプロシージャを呼び出すことでした。.asmxファイルでRAISEERROR()によってトリガされたSQLストアドプロシージャエラーをキャプチャするにはどうすればよいですか?

私はDatabase.ExecuteNonQuery()でいくつかのコマンドを呼び出しています。 SQLストアドプロシージャでは、渡されたLoginIdに基づいていくつかのセキュリティチェックを実行しています(ユーザーは所有者であるアイテムのみを編集できます)。セキュリティチェックに失敗した場合、RAISEERROR()を呼び出すとエラーが発生しますが、.asmxファイルではこれが例外として認識されず、単にストアドプロシージャが終了します。

私の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"); 
    } 
} 

私の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 

答えて

1

私は次のように私のストアドプロシージャを更新:

/* 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 

そして、私はこのように私の.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); 
2

問題は、エラー重大度、それが低すぎるということです。重大度1〜10は情報メッセージとして扱われ、C#アプリケーションの流れを壊さない。

answerより詳細な説明はRemus Rusanuです。

+0

おかげで@ahsteele。意味あり。私は記述した条件の下で別のコードを返すようにロジックを変更し、C#でリターンコードを処理しました(下記参照)。 –

関連する問題