处理ASP.NET Web服务方法退出

时间:2009-07-07 15:32:16

标签: web-services asmx

假设我有一个适用于数据库的Web服务。每个方法都会打开数据库,然后在退出时关闭它。

是否有任何方法可以将开放/关闭代码移到Web方法本身之外?像OnBeforeWebMethodCalled / OnAfterWebMethodCalled。

所以而不是

[WebMethod]
public void Hello()
{
   OpenDatabase();
   try { } finally { CloseDatabase(); }
}

我们将

private void OnBeforeWebMethodCalled() { OpenDatabase(); }
private void OnAfterWebMethodCalled() { CloseDatabase(); }
[WebMethod]
public void Hello()
{
  // the database is ready here
}

感谢大家提出使用关键字,但我知道。问题是我有第一种遗留服务,我想轻松地将数据库包装成第二种。

现在,想象一下它不是数据库的东西。成像我想记录Web方法的进入/退出。或者我想发送有关调用哪种方法的电子邮件。随你。我真正需要的是在web方法的入口/出口处执行一些代码。我不想将此代码注入每个Web方法。理想情况下,如果我也可以捕捉异常。

4 个答案:

答案 0 :(得分:2)

这是一个非常糟糕的主意。

首先,您的数据库访问应该包含在using语句中。如果你不打算这样做,那么至少你需要的是试试。

其次,Web服务运行时如何知道您是否真的需要打开数据库连接?

最后如果db调用爆炸怎么办?您的Web方法将如何处理孤立连接?或者,如果打开失败,web方法会做什么?

答案 1 :(得分:1)

拥有一个私有方法,可以让您获得开放的数据库连接。在使用区块中包裹它,然后它将被正确关闭/处理,而不必考虑它。

private IDbConnection GetDbConn()
{
    SqlConnection conn = new SqlConnection("connectionstringhere");
    conn.Open();
    return conn;
}

[WebMethod]
public void SomeWebMethod()
{
    using (IDbConnection conn = GetDbConn())
    {
        // your code here
    }
}

<强>跟进

如果不在每个网络方法中添加try {} catch {},我真的不知道如何捕获异常。

关于在每个Web方法的开头和结尾运行某些东西,也许您可​​以查看触发事件,将Web连接到Web服务的构造函数中。

如果您需要保证无论您的Web方法是否引发异常,都会触发“end”事件,请将其放在finally {}块中。

这需要您编辑一次Web方法以添加事件代码,但是您可以根据需要从一个中心位置(构造函数)添加/删除事件处理程序。

[WebService(Namespace = "http://YourWebServiceNamespace")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
public class YourWebService : System.Web.Services.WebService
{
  private event EventHandler WebMethodStarted;
  private event EventHandler WebMethodCompleted;

  public YourWebService()
  {
     WebMethodStarted += new EventHandler(YourWebService_WebMethodStarted);
     WebMethodCompleted += new EventHandler(YourWebService_WebMethodCompleted);
  }

  [WebMethod]
  public void SomeWebMethod()
  {
      OnWebServiceStarted();

      try
      {
          // your code here
      }
      catch
      {
          // this is where I suggest you do your exception handling for each webmethod
      }
      finally
      {
          OnWebServiceCompleted();
      }
  } 


  private void OnWebMethodStarted()
  {
      if (WebMethodStarted != null)
          WebMethodStarted(this, EventArgs.Empty);
  }    

  private void OnWebMethodCompleted()
  {
      if (WebMethodCompleted != null)
          WebMethodCompleted(this, EventArgs.Empty);
  }    

  private void YourWebService_WebMethodStarted(object sender, EventArgs e)
  {
      throw new NotImplementedException(); // your code here
  }

  private void YourWebService_WebMethodCompleted(object sender, EventArgs e)
  {
      throw new NotImplementedException(); // your code here
  }
}

答案 2 :(得分:1)

我偶然发现了这个问题的可能解决方案

http://www.postsharp.org/

答案 3 :(得分:0)

您应该使用存储库类封装其自身的open和close方法。在某种程度上,在前端打开和关闭数据库连接是一种不好的做法。

public static class DBRepository
{

    public static void SomeOps(string args)
    {
        //open db
        //your ops
        //close db
    }

}

从web-service调用DBRepository.SomeOps。