前一陣子應客戶需求
獨立負責令一個專案開發
架構要跟原本開發的案子一樣
所以我直接複製整個專案,改名,再做一些加工後就丟上 TFS
但是修改過的檔案都不會自動出現在包含的變更(Pending Changes)清單
讓人困擾
解決方式:
檔案 → 原始檔控制 → 進階 → 變更原始檔控制 → 全選 繫結 → 簽入
2016年9月10日
2016年7月21日
Bootstrap modal prevent close (datepicker input in modal)
有個功能是 Bootstrap modal內有 datepicker input,還有一個 OK按鈕
如果不是按 OK就把 modal關閉的話,modal中輸入欄位的值要還原
如果是按 OK關閉 modal的話,檢核輸入值,檢核未過則 modal取消關閉
搜尋取消關閉 modal的範例後寫出大致如下的程式:
Bootstrap modal的官方文件中有說明 events還有一種 hidden.bs.modal,直接拿來套用,改成
但是另一個問題又來了,preventDefault、stopImmediatePropagation現在無效了
因為英文不好,對 Bootstrap modal官方文件的 Events說明琢磨了一會還是看不懂差異在哪:
只好寫程式來觀察:
hide.bs.modal是關閉前觸發,但是 modal內的 datepicker關閉時也會觸發 hide.bs.modal
所以改成先判斷 hide.bs.modal是否為 datepicker被關閉時觸發即可
如果不是按 OK就把 modal關閉的話,modal中輸入欄位的值要還原
如果是按 OK關閉 modal的話,檢核輸入值,檢核未過則 modal取消關閉
搜尋取消關閉 modal的範例後寫出大致如下的程式:
$('.modal').on('hide.bs.modal', function (e) {
if (CheckClosedByBtnOK()) {
if (!ValidInput()) {
e.preventDefault();
e.stopImmediatePropagation();
}
}
else {
ResetInput();
}
});
但是發現使用 datepicker選完日期並關閉小視窗後也會觸發 hide.bs.modal,導致每次選完值就還原,有選跟沒選一樣Bootstrap modal的官方文件中有說明 events還有一種 hidden.bs.modal,直接拿來套用,改成
$('.modal').on('hidden.bs.modal', function (e) { ...
現在不會選完值就還原了,也就是 hidden.bs.modal只有在 modal關閉時才會觸發,datepicker關閉時不會但是另一個問題又來了,preventDefault、stopImmediatePropagation現在無效了
因為英文不好,對 Bootstrap modal官方文件的 Events說明琢磨了一會還是看不懂差異在哪:
hide.bs.modal | This event is fired immediately when the hide instance method has been called. |
hidden.bs.modal | This event is fired when the modal has finished being hidden from the user (will wait for CSS transitions to complete). |
只好寫程式來觀察:
$('.modal').on('hide.bs.modal', function (e) {
console.log(this);
console.log('hide');
}).on('hidden.bs.modal', function (e) {
console.log(this);
console.log('hidden');
});
得出 hidden.bs.modal是在 modal被關閉後才觸發,所以 preventDefault當然沒有效果hide.bs.modal是關閉前觸發,但是 modal內的 datepicker關閉時也會觸發 hide.bs.modal
所以改成先判斷 hide.bs.modal是否為 datepicker被關閉時觸發即可
var isUsingDatepicker = false;
$('.modal').on('show.bs.modal', function (e) {
isUsingDatepicker = ($(div.datepicker-dropdown).length > 0);
}).on('hide.bs.modal', function (e) {
if (!isUsingDatepicker) {
if (CheckClosedByBtnOK()) {
if (!ValidInput()) {
e.preventDefault();
e.stopImmediatePropagation();
}
}
else {
ResetInput();
}
}
isUsingDatepicker = ($(div.datepicker-dropdown).length > 0);
});
2016年4月21日
2016年2月1日
提早 Timeout
客戶反應未到四小時就被登出
檢查 Web程式的 web.config
Session Timeout和 Form Auth Timeout都是設定 240(分)
Log紀錄也有正常的 Timeout紀錄
可能是因為 Load Balance的 Sticky Timeout只設 60(分)
檢查 Web程式的 web.config
Session Timeout和 Form Auth Timeout都是設定 240(分)
Log紀錄也有正常的 Timeout紀錄
可能是因為 Load Balance的 Sticky Timeout只設 60(分)
2015年11月16日
2015年10月28日
javascript 一個元件用兩個 class註冊同一種事件的觸發順序
<input class="A B" />
$('.A').keyup(function () {
...
});
$(document).delegate('.B', 'keyup', function () {
...
});
B會比 A先執行
2015年10月23日
2015年8月7日
2015年7月31日
Log4Net 學習紀錄
1.NuGet install log4net
2.Cerate file log4net.config
儲存GUID
Trace log4net debug message by modify web.config
2.Cerate file log4net.config
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
</configuration>
<configuration>
<!--logger: 記錄器,可自訂設定屬性(可多個)-->
<!--appender-ref: 指定參考的Appender設定-->
<logger name="Rolling">
<appender-ref ref="RollingFile" />
</logger>
<logger name="DB">
<appender-ref ref="LogDatabase" />
</logger>
</configuration>
<configuration>
<!--root logger: 根記錄器,當其他記錄器執行完後最後會執行根記錄器(唯一)-->
<!--level: 記錄級別設定-->
<root>
<level value="DEBUG" />
<appender-ref ref="RollingFile" />
</root>
</configuration>
For File
<configuration>
<!--appender: 內容為輸出格式的設定-->
<!--type: 輸出類型,例如 ConsoleAppender 為主控台輸出、RollingFileAppender 為文字檔輸出-->
<!--file: 輸出檔案的路徑位置-->
<!--layout: 記錄的格式設定-->
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file value="C:\Log\PlayLog.txt" />
<appendToFile value="true" />
<maximumFileSize value="1000KB" />
<maxSizeRollBackups value="2" />
<rollingStyle value="Date" />
<datePattern value="yyyyMMdd" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="[Activity]%newlineActivityId: %property{GUID}%newlineTime: %date{yyyy-MM-dd HH:mm:ss}%newlineLevel: %level%newline%newline[System]%newlineSystem: %property{System}%newline%newline[IP]%newlineServerIP: %property{ServerIP}%newlineClientIP: %property{ClientIP}%newline%newline[Message]%newlineDescription: %property{Description}%newlineException: %property{Exception}%newline%newline[Properties]%newline%message%newline%newline" />
</layout>
</appender>
</configuration>
For DB
<configuration>
<appender name="LogDatabase" type="log4net.Appender.AdoNetAppender">
<bufferSize value="100" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=4.0.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089" />
<connectionString value="Data Source={Server};Initial Catalog={DBName};User ID={UserID};Password={Password}" />
<commandText value="INSERT INTO [dbo].[Message] (MessageId, Message) VALUES (@MessageId, @Message)" />
<parameter>
<parameterName value="@MessageId" />
<dbType value="Int32" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{MessageId}" />
</layout>
</parameter>
<parameter>
<parameterName value="@Message" />
<dbType value="String" />
<size value="100" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{Message}" />
</layout>
</parameter>
</appender>
</configuration>
3.Add Watch in Global.asax Application_Start()log4net.Config.XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo(Server.MapPath("~/log4net.config")));
儲存GUID
log4net.ThreadContext.Properties["GUID"] = guidValue;
<parameter>
<parameterName value="@LogId" />
<dbType value="Guid" />
<layout type="log4net.Layout.RawPropertyLayout">
<key value="GUID" />
</layout>
</parameter>
Trace log4net debug message by modify web.config
<configuration>
<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>
</configuration>
<configuration>
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add name="textWriterTraceListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="C:\Log\log4net.txt"
/>
</listeners>
</trace>
</system.diagnostics>
</configuration>
2015年7月28日
2015年5月14日
繳費疑雲
一個帳號前後有兩個擁有者A,B
A把帳號讓渡給B了
B去查帳單的時候,A、B的兩個時期的帳單都有
B把所有帳單都繳掉了
這時查繳費紀錄只會出現B的資料
A去查繳費紀錄時就查不到了
user卻想在繳費紀錄看到“誰產生帳單的”
A把帳號讓渡給B了
B去查帳單的時候,A、B的兩個時期的帳單都有
B把所有帳單都繳掉了
這時查繳費紀錄只會出現B的資料
A去查繳費紀錄時就查不到了
user卻想在繳費紀錄看到“誰產生帳單的”
2015年4月20日
2015年4月17日
foreach 物件屬性
foreach (PropertyInfo property in obj.GetType().GetProperties())
{
if (property.GetValue(obj, null) != null)
{
property.SetValue(obj, "");
}
}
2015年4月1日
前端頁面使用者操作紀錄
在遠通的專案,發生了 end-user在 CSS系統繳費,說是只繳兩筆,但是系統銷帳卻有三筆的狀況
但是因為沒有頁面元件操作紀錄,所以死無對証
解決的方法可以考慮在 checkbox綁 onclick,每按一下就紀錄下來,submit的時候一併送出,再寫入 log
但是因為沒有頁面元件操作紀錄,所以死無對証
解決的方法可以考慮在 checkbox綁 onclick,每按一下就紀錄下來,submit的時候一併送出,再寫入 log
2015年3月31日
.NET SqlParameter(string paraName, object value) 字串 NVarchar
最近程式再被調教中
收到一封 mail說我們的 SQL script都是用 nvarchar,效能較差
要我們改成 varchar
查了一下是因為底層的 function寫得太便利,大家都是丟 object[] 進去直接賦值 大概是像這樣子
如果 value是 int、dobule、datetime等都沒問題,產生出來的 SqlParameter內的屬性 SqlDbType會自動轉成對應的類別
但如果是字串,不管是 string、String還是 char,一律會被轉成 nvarchar
問題就來了
因為 table schema是放 varchar,query script的 where條件被轉成 nvarchar,就會導致效能變差~
收到一封 mail說我們的 SQL script都是用 nvarchar,效能較差
要我們改成 varchar
查了一下是因為底層的 function寫得太便利,大家都是丟 object[] 進去直接賦值 大概是像這樣子
SqlParameter sqlPara = new SqlParameter("@" + temp[0], paraValues[i]);
如果 value是 int、dobule、datetime等都沒問題,產生出來的 SqlParameter內的屬性 SqlDbType會自動轉成對應的類別
但如果是字串,不管是 string、String還是 char,一律會被轉成 nvarchar
問題就來了
因為 table schema是放 varchar,query script的 where條件被轉成 nvarchar,就會導致效能變差~