これは楽しいものです。
デフォルトの連絡先ビューよりも高速でユーザーフレンドリーな検索を提供し、リードと連絡先を同時に検索できるカスタム検索ページを作成しました。フィルタリングされたビューをクエリするSqlDataSourcesにバインドされたGridViewsを使用します。誰かが私がこれにWebサービスを使用していないと不平を言うと確信していますが、これは私たちが行った設計上の決定にすぎません。
これらのGridViewはUpdatePanelsに存在し、検索時に非常に洗練されたAJAX更新を可能にします。
それはすべてうまく機能しています。1つを除いて、ほぼデプロイの準備ができています。長時間実行される検索の中には、キャッチできない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)
このエラーが発生したときにUpdatePanelsがJavaSriptエラーをスローし始めたため、CRMがこのエラーをキャプチャするためにserver.transferを実行していることがわかりました。IEでJavaScriptデバッガーを使用することによってのみ、完全なエラーメッセージを取得できました。
このエラーを見つけたので、解決策は簡単だと思いました。エラーをキャプチャするには、databind呼び出しをtry/catchブロックでラップする必要がありました。
残念ながら、CRMのIIS構成には、コードに戻る前にこのエラーをキャプチャする魔法の機能があるようです。デバッガーを使用すると、私はそれを見ることはありません。それは私のキャッチブロックに到達することはありませんが、それは明らかに(スタックトレースによって)私のGridViewバインドによってトリガーされているSQLデータソースで発生しています。
これについて何かアイデアはありますか?それは私を夢中にさせています。
コードビハインド(一部の無関係な関数は省略されています):
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();
}