在我能够处理之前,MS Dynamics CRM会捕获.NET错误

时间:2010-05-10 16:01:28

标签: .net gridview dynamics-crm sqldatasource

这是一个有趣的。

我编写了一个自定义搜索页面,提供比默认联系人视图更快,更友好的搜索,还允许同时搜索潜在客户和联系人。它使用绑定到SqlDataSources的GridViews来查询过滤后的视图。我相信有人会抱怨我没有使用网络服务,但这只是我们做出的设计决定。

这些GridViews位于UpdatePanels中,可在搜索时启用非常灵活的AJAX更新。

一切都很好。几乎准备好部署,除了一件事:一些长时间运行的搜索触发了一个无法捕获的SQL超时异常。

    [SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.]
  at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
  at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
  at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
  at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
  at System.Data.SqlClient.SqlDataReader.ConsumeMetaData()
  at System.Data.SqlClient.SqlDataReader.get_MetaData()
  at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
  at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
  at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
  at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
  at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
  at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
  at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior)
  at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
  at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
  at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, String srcTable)
  at System.Web.UI.WebControls.SqlDataSourceView.ExecuteSelect(DataSourceSelectArguments arguments)
  at System.Web.UI.DataSourceView.Select(DataSourceSelectArguments arguments, DataSourceViewSelectCallback callback)
  at System.Web.UI.WebControls.DataBoundControl.PerformSelect()
  at System.Web.UI.WebControls.BaseDataBoundControl.DataBind()
  at System.Web.UI.WebControls.GridView.DataBind()
  at System.Web.UI.WebControls.BaseDataBoundControl.EnsureDataBound()
  at System.Web.UI.WebControls.CompositeDataBoundControl.CreateChildControls()
  at System.Web.UI.Control.EnsureChildControls()
  at System.Web.UI.Control.PreRenderRecursiveInternal()
  at System.Web.UI.Control.PreRenderRecursiveInternal()
  at System.Web.UI.Control.PreRenderRecursiveInternal()
  at System.Web.UI.Control.PreRenderRecursiveInternal()
  at System.Web.UI.Control.PreRenderRecursiveInternal()
  at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

我发现CRM正在执行server.transfer来捕获此错误,因为我的UpdatePanels会在发生此错误时开始抛出JavaSript错误。我只能通过在IE中使用JavaScript调试器来获取完整的错误消息。

发现此错误后,我认为解决方案很简单。我只需要在try / catch块中包装我的数据绑定调用来捕获任何错误。

不幸的是,似乎CRM的IIS配置具有捕获此错误的神奇功能,然后才能返回到我的代码。使用调试器我从来没有看到它。它永远不会到达我的catch块,但它显然发生在SQL数据源中,显然(通过堆栈跟踪)由我的GridView绑定触发。

有关于此的任何想法吗?这让我发疯了。

Code Behind(省略了一些不相关的功能):

  protected void Page_Load(object sender, EventArgs e)
  {
    //Initialize some stuff
    this.bannerOracle = new OdbcConnection(ConfigurationManager.ConnectionStrings["OracleConnectionString"].ConnectionString);

    //Prospect default
    HideProspects();
    HideProspectAddressColumn();

    //Contacts default
    HideContactAddressColumn();

    //Default error messages
    gvContacts.EmptyDataText = "Sad day. Your search returned no contacts.";
    gvProspects.EmptyDataText = "Sad day. Your search returned no prospects.";

    //New search
    try
    {
      SearchContact(null, -1);
    }
    catch
    {
      gvContacts.EmptyDataText = "Oops! An error occured. This may have been a timeout. Please try your search again.";
      gvContacts.DataSource = null;
      gvContacts.DataBind();
    }
  }
  protected void txtSearchString_TextChanged(object sender, EventArgs e)
  {
    if(!String.IsNullOrEmpty(txtSearchString.Text))
    {
      try
      {
        SearchContact(txtSearchString.Text, Convert.ToInt16(lstSearchType.SelectedValue));
      }
      catch
      {
        gvContacts.EmptyDataText = "Oops! An error occured. This may have been a timeout. Please try your search again."; 
        gvContacts.DataSource = null;
        gvContacts.DataBind();
      }

      if (chkProspects.Checked == true)
      {
        try
        {
          SearchProspect(txtSearchString.Text, Convert.ToInt16(lstSearchType.SelectedValue));
        }
        catch
        {
          gvProspects.EmptyDataText = "Oops! An error occured. This may have been a timeout. Please try your search again.";
          gvProspects.DataSource = null;
          gvProspects.DataBind();
        }
        finally
        {
          ShowProspects();
        }
      }
      else
      {
        HideProspects();
      }
    }
  }
  protected void SearchContact(string search, int type)
  {
    SqlCRM_Contact.ConnectionString = ConfigurationManager.ConnectionStrings["MSSQLConnectionString"].ConnectionString;
    gvContacts.DataSourceID = "SqlCRM_Contact";

    string strQuery = "";
    string baseQuery = @"SELECT filteredcontact.contactid,
                 filteredcontact.new_libertyid,
                 filteredcontact.fullname,
                 'none' AS line1,
                 filteredcontact.emailaddress1,
                 filteredcontact.telephone1,
                 filteredcontact.birthdateutc AS birthdate,
                 filteredcontact.gendercodename
              FROM filteredcontact "; 
    switch(type)
    {
      case LASTFIRST:
        strQuery = baseQuery + "WHERE fullname LIKE @value AND filteredcontact.statecode = 0";
        SqlCRM_Contact.SelectCommand = strQuery;
        SqlCRM_Contact.SelectParameters.Add("value", DbType.String, search.Trim() + "%");
        break;
      case LAST:
        strQuery = baseQuery + "WHERE lastname LIKE @value AND filteredcontact.statecode = 0";
        SqlCRM_Contact.SelectCommand = strQuery;
        SqlCRM_Contact.SelectParameters.Add("value", DbType.String, search.Trim() + "%");
        break;
      case FIRST:
        strQuery = baseQuery + "WHERE firstname LIKE @value AND filteredcontact.statecode = 0";
        SqlCRM_Contact.SelectCommand = strQuery;
        SqlCRM_Contact.SelectParameters.Add("value", DbType.String, search.Trim() + "%");
        break;
      case LIBERTYID:
        strQuery = baseQuery + "WHERE new_libertyid LIKE @value AND filteredcontact.statecode = 0";
        SqlCRM_Contact.SelectCommand = strQuery;
        SqlCRM_Contact.SelectParameters.Add("value", DbType.String, search.Trim() + "%");
        break;
      case EMAIL:
        strQuery = baseQuery + "WHERE emailaddress1 LIKE @value AND filteredcontact.statecode = 0";
        SqlCRM_Contact.SelectCommand = strQuery;
        SqlCRM_Contact.SelectParameters.Add("value", DbType.String, search.Trim() + "%");
        break;
      case TELEPHONE:
        strQuery = baseQuery + "WHERE telephone1 LIKE @value AND filteredcontact.statecode = 0";
        SqlCRM_Contact.SelectCommand = strQuery;
        SqlCRM_Contact.SelectParameters.Add("value", DbType.String, search.Trim() + "%");
        break;
      case BIRTHDAY:
        strQuery = baseQuery + "WHERE filteredcontact.birthdateutc BETWEEN @dateStart AND @dateEnd AND filteredcontact.statecode = 0";
        try
        {
          DateTime temp = DateTime.Parse(search);
          if (temp.Year < 1753 || temp.Year > 9999)
          {
            search = string.Empty;
          }
          else
          {
            search = temp.ToString("yyyy-MM-dd");
          }
        }
        catch
        {
          search = string.Empty;
        }
        SqlCRM_Contact.SelectCommand = strQuery;
        SqlCRM_Contact.SelectParameters.Add("dateStart", DbType.String, search.Trim() + " 00:00:00.000");
        SqlCRM_Contact.SelectParameters.Add("dateEnd", DbType.String, search.Trim() + " 23:59:59.999");
        break;
      case SSN:
        //Do something
        break;
      case ADDRESS:
        strQuery = @"SELECT contactid,
               new_libertyid,
               fullname,
               line1,
               emailaddress1,
               telephone1,
               birthdate,
               gendercodename 
               FROM (SELECT FC.contactid,
                     FC.new_libertyid,
                     FC.fullname,
                     FA.line1,
                     FC.emailaddress1,
                     FC.telephone1,
                     FC.birthdateutc AS birthdate,
                     FC.gendercodename,
                     ROW_NUMBER() OVER(PARTITION BY FC.contactid ORDER BY FC.contactid DESC) AS rn 
                    FROM filteredcontact FC 
                    INNER JOIN FilteredCustomerAddress FA
                    ON FC.contactid = FA.parentid
                    WHERE FA.line1 LIKE @value AND FA.addressnumber <> 1 AND FC.statecode = 0 ) AS RESULTS
               WHERE rn = 1";
        SqlCRM_Contact.SelectCommand = strQuery;
        SqlCRM_Contact.SelectParameters.Add("value", DbType.String, search.Trim() + "%");
        ShowContactAddressColumn();
        break;
      default:
        strQuery = @"SELECT TOP 500 filteredcontact.contactid,
                 filteredcontact.new_libertyid,
                 filteredcontact.fullname,
                 'none' AS line1,
                 filteredcontact.emailaddress1,
                 filteredcontact.telephone1,
                 filteredcontact.birthdateutc AS birthdate,
                 filteredcontact.gendercodename
              FROM filteredcontact 
              WHERE filteredcontact.statecode = 0";
        SqlCRM_Contact.SelectCommand = strQuery;
        break;
    }
    if (type != ADDRESS)
    {
      HideContactAddressColumn();
    }
    gvContacts.PageIndex = 0;
    //try
    //{
    //  SqlCRM_Contact.DataBind();
    //}
    //catch
    //{
    //  SqlCRM_Contact.DataBind();
    //}
    gvContacts.DataBind();
  }
  protected void SearchProspect(string search, int type)
  {
    SqlCRM_Prospect.ConnectionString = ConfigurationManager.ConnectionStrings["MSSQLConnectionString"].ConnectionString;
    gvProspects.DataSourceID = "SqlCRM_Prospect";

    string strQuery = "";
    string baseQuery = @"SELECT filteredlead.leadid,
                 filteredlead.fullname,
                 'none' AS address1_line1,
                 filteredlead.emailaddress1,
                 filteredlead.telephone1,
                 filteredlead.lu_dateofbirthutc AS lu_dateofbirth,
                 filteredlead.lu_gendername
              FROM filteredlead ";

    switch (type)
    {
      case LASTFIRST:
        strQuery = baseQuery + "WHERE fullname LIKE @value AND filteredlead.statecode = 0";
        SqlCRM_Prospect.SelectCommand = strQuery;
        SqlCRM_Prospect.SelectParameters.Add("value", DbType.String, search.Trim() + "%");
        break;
      case LAST:
        strQuery = baseQuery + "WHERE lastname LIKE @value AND filteredlead.statecode = 0";
        SqlCRM_Prospect.SelectCommand = strQuery;
        SqlCRM_Prospect.SelectParameters.Add("value", DbType.String, search.Trim() + "%");
        break;
      case FIRST:
        strQuery = baseQuery + "WHERE firstname LIKE @value AND filteredlead.statecode = 0";
        SqlCRM_Prospect.SelectCommand = strQuery;
        SqlCRM_Prospect.SelectParameters.Add("value", DbType.String, search.Trim() + "%");
        break;
      case LIBERTYID:
        strQuery = baseQuery + "WHERE new_libertyid LIKE @value AND filteredlead.statecode = 0";
        SqlCRM_Prospect.SelectCommand = strQuery;
        SqlCRM_Prospect.SelectParameters.Add("value", DbType.String, search.Trim() + "%");
        break;
      case EMAIL:
        strQuery = baseQuery + "WHERE emailaddress1 LIKE @value AND filteredlead.statecode = 0";
        SqlCRM_Prospect.SelectCommand = strQuery;
        SqlCRM_Prospect.SelectParameters.Add("value", DbType.String, search.Trim() + "%");
        break;
      case TELEPHONE:
        strQuery = baseQuery + "WHERE telephone1 LIKE @value AND filteredlead.statecode = 0";
        SqlCRM_Prospect.SelectCommand = strQuery;
        SqlCRM_Prospect.SelectParameters.Add("value", DbType.String, search.Trim() + "%");
        break;
      case BIRTHDAY:
        strQuery = baseQuery + "WHERE filteredlead.lu_dateofbirth BETWEEN @dateStart AND @dateEnd AND filteredlead.statecode = 0";
        try
        {
          DateTime temp = DateTime.Parse(search);
          if (temp.Year < 1753 || temp.Year > 9999)
          {
            search = string.Empty;
          }
          else
          {
            search = temp.ToString("yyyy-MM-dd");
          }
        }
        catch
        {
          search = string.Empty;
        }
        SqlCRM_Prospect.SelectCommand = strQuery;
        SqlCRM_Prospect.SelectParameters.Add("dateStart", DbType.String, search.Trim() + " 00:00:00.000");
        SqlCRM_Prospect.SelectParameters.Add("dateEnd", DbType.String, search.Trim() + " 23:59:59.999");
        break;
      case SSN:
        //Do nothing
        break;
      case ADDRESS:
        strQuery = @"SELECT filteredlead.leadid,
                 filteredlead.fullname,
                 filteredlead.address1_line1,
                 filteredlead.emailaddress1,
                 filteredlead.telephone1,
                 filteredlead.lu_dateofbirthutc AS lu_dateofbirth,
                 filteredlead.lu_gendername
              FROM filteredlead WHERE address1_line1 LIKE @value AND filteredlead.statecode = 0";
        SqlCRM_Prospect.SelectCommand = strQuery;
        SqlCRM_Prospect.SelectParameters.Add("value", DbType.String, search.Trim() + "%");
        ShowProspectAddressColumn();
        break;
      default:
        strQuery = @"SELECT TOP 500 filteredlead.leadid,
                 filteredlead.fullname,
                 'none' AS address1_line1
                 filteredlead.emailaddress1,
                 filteredlead.telephone1,
                 filteredlead.lu_dateofbirthutc AS lu_dateofbirth,
                 filteredlead.lu_gendername
              FROM filteredlead WHERE filteredlead.statecode = 0";
        SqlCRM_Prospect.SelectCommand = strQuery;
        break;
    }
    if (type != ADDRESS)
    {
      HideProspectAddressColumn();
    }
    gvProspects.PageIndex = 0;
    //try
    //{
    //  SqlCRM_Prospect.DataBind();
    //}
    //catch (Exception ex)
    //{
    //  SqlCRM_Prospect.DataBind();
    //}
    gvProspects.DataBind();
  }

2 个答案:

答案 0 :(得分:1)

使用SqlDataSource的{​​{3}}事件,检查Selected属性以查看是否发生了异常。您还可以使用Exception属性来表明您已处理该事件。

P.S。请注意我发布的代码中有多少是我回答问题所必需的。

答案 1 :(得分:0)

我不确定为什么你不能捕获异常,但我的猜测是因为数据绑定魔法。但是,您至少可以增加超时时间:

http://blog.customereffective.com/blog/2008/07/increase-crm-sq.html

希望有所帮助!