¿Cómo puedo capturar un Procedimiento Almacenado de SQL Error provocado por RAISEERROR() en .asmx archivo?

StackOverflow https://stackoverflow.com/questions/1104725

Pregunta

Estoy muy nuevo .NET.Todo lo que he hecho hasta ahora es aplicar algún Procedimiento Almacenado de SQL llamadas como WebServices con copiar y pegar el código existente (como se ha indicado por parte de mi superior).

Estoy llamando a algunos comandos a través de Database.ExecuteNonQuery().En el Procedimiento Almacenado de SQL, estoy realizando algunas comprobaciones de seguridad basado en el nombre de usuario que pasó (un usuario sólo puede editar los elementos de los que es propietario).Si la comprobación de seguridad falla, yo estoy llamando RAISEERROR() para desencadenar un error, pero mi .asmx archivo no está viendo esto como una excepción, y simplemente se sale del Procedimiento Almacenado.

Mi asmx archivo:

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

Mi Procedimiento Almacenado de 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
¿Fue útil?

Solución 2

He actualizado mi procedimiento almacenado con lo siguiente:

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

Y que manejo en mi archivo .asmx como esto:

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);

Otros consejos

El problema es que el error Gravedad demasiado bajo. Severidades 1 -. 10 se tratan como mensajes de información y no se rompen el flujo de una aplicación de C #

una explicación más detallada se puede encontrar en una responder de Remus Ruşanu .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top