【问题标题】:How to handle stored procedure raiserror in mvc controller如何在 mvc 控制器中处理存储过程 raiserror
【发布时间】:2015-07-07 12:35:48
【问题描述】:

我正在使用数据库优先方法开发一个 asp.net mvc 站点。

我有一个像这样的简单存储过程:

ALTER PROCEDURE [dbo].[ins_item]
    -- Add the parameters for the stored procedure here
    -- item supplied must be in the reference db
    @item varchar(50)
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here
    select item 
    from reference.dbo.all_items 
    where item_name = @item

    if @@ROWCOUNT !=1
    begin
        raiserror('supplied item is not found in the master item list.', 11,1)
            return -1
    end
    --Now you know the item is in the reference, insert and handle any errors
END

当我在 SQL Server Management Studio 中使用参考数据库中不存在的项目执行此操作时,我按预期收到此错误:

消息 50000,级别 11,状态 1,过程 ins_item,行 xx
在主项目列表中找不到提供的项目。

在我的 asp.net mvc 应用程序中,我将此存储过程导入到我的模型中,并且在我的一个控制器中,我有以下代码:

public ActionResult Create(item item)
{
    if (ModelState.IsValid)
    {
        try
        {
            var insertresult =  db.ins_item(item.item1);

            db.SaveChanges();
        }
        catch (Exception e)
        {
            ViewBag.error = e;
        }

        return RedirectToAction("Index");
    }

    return View(item);
}

db.ins_item 在我模型的数据库上下文中看起来像这样,它继承自 DbContext 类:

public virtual ObjectResult<string> ins_item(string item)
{
    var itemParameter = item!= null ?
                new ObjectParameter("item", item) :
                new ObjectParameter("item", typeof(string));

    return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<string>("ins_item", itemParameter);
}

问题是执行此操作时我没有收到异常。如何捕捉存储过程在上述控制器操作中返回的 raiserror?

【问题讨论】:

  • 您能否检查一下您的情况下的返回值(-1)并将其作为异常处理

标签: c# asp.net-mvc-4


【解决方案1】:

我不使用 ObjectContext 但 DataContext 这是推荐的方式。为了获得这些消息,您需要添加以下内容:

var sqlConnection = dbContext.Database.Connection as SqlConnection;
if (sqlConnection != null)
{
    sqlConnection.InfoMessage += InfoMessageEventHandler;
}

private void InfoMessageEventHandler(object sender, SqlInfoMessageEventArgs e)
{
    // code to save error or warning message 
}

考虑到此事件在存储过程结束时触发,因此您不会收到实时通知。

重要的是要强调这不是作为异常进行管理的,这就是我们需要显式订阅 InfoMessage 事件的原因。

另一方面,您可以使用 DbContext 而不是 ObjectContext(旧方式)来执行存储过程。例如:

dbContext.Database.CommandTimeout = 240;
return dbContext.Database.SqlQuery<string>("spName {0}", value);

您也可以传递 SqlParameters 列表而不是 value。

【讨论】:

  • 我尝试了旧方法,但也没有引发任何异常。关于InfoMessageEventHandler,我把这段代码放在哪里?
  • 也不例外,它是一条信息消息,这就是为什么你需要订阅事件InfoMessage。您应该将此代码放在数据层中,但出于测试目的,您可以订阅创建连接对象的事件。
  • 正如我在问题中提到的,我正在使用 DbContext。 DbContext.Database.Connection 上没有 InfoMessage
  • 那是因为您需要像这样将连接转换为 SqlConnection: var sqlConnection = dbContext.Database.Connection as SqlConnection;我将其添加到我的答案中。
  • 试过了,没有触发
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-04
  • 1970-01-01
相关资源
最近更新 更多