0

这是一个有趣的。

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

这些 GridView 存在于 UpdatePanel 中,以便在搜索时启用非常流畅的 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 绑定触发的(通过堆栈跟踪)。

对此有什么想法吗?这让我疯狂。

后面的代码(省略了一些不相关的功能):

  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();
  }
4

2 回答 2

1

Use the Selected event of the SqlDataSource, and examine the Exception property to see if an exception has occurred. You can also use the ExceptionHandled property to indicate that you have handled the event.

P.S. Note how much of your posted code was necessary for me to answer the question.

于 2010-05-10T18:30:17.977 回答
0

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

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

希望有帮助!

于 2010-05-10T18:21:41.220 回答