这是一个有趣的。
我编写了一个自定义搜索页面,提供比默认联系人视图更快,更友好的搜索,还允许同时搜索潜在客户和联系人。它使用绑定到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();
}
答案 0 :(得分:1)
使用SqlDataSource
的{{3}}事件,检查Selected
属性以查看是否发生了异常。您还可以使用Exception
属性来表明您已处理该事件。
P.S。请注意我发布的代码中有多少是我回答问题所必需的。
答案 1 :(得分:0)
我不确定为什么你不能捕获异常,但我的猜测是因为数据绑定魔法。但是,您至少可以增加超时时间:
http://blog.customereffective.com/blog/2008/07/increase-crm-sq.html
希望有所帮助!