2016年10月3日

[Mac] 設定 Mac 通訊錄讀取 Zimbra 全域聯絡人(更新 macOS Sierra)

Step 1. 聯絡資訊 --> 帳號...


Step 2. 用「加入其他帳號 ...」來新增帳號

Step 3. 選擇 CardDAV 帳號


Step 4. 這邊的伺服器路徑設成: /principals/users/galsync/




Step 5.  前項步驟完成後,回到「聯絡人資訊」,再從「偏好設定」進入。


Step 6. 這邊的伺服器路徑改成「/dav/galsync」





2016年6月4日

[.Net] System.Net.Mail 寄信到 Zimbra 主旨亂碼的問題


如下圖,主旨太長就被截斷
根據 RFC2047 上講的
An 'encoded-word' may not be more than 75 characters long
看樣子要嘛就是 Zimbra 處理的時候有問題,要嘛就是 System.Net.Mail 發信的時候處理有問題。

顯示信件原始內容來看,直接拿 subject 裡最後一行去解 Base64 會發現有亂碼!
解回來的內容開頭是亂碼:

問題追到這邊大概有答案了,就是 System.Net.Mail 雖然會幫我們處理不能超過 75 個字元的問題,但是沒有考慮到雙位元的文字處理,而 Zimbra 分段去處理主旨的編碼,就會造成中文字被分割成兩個半的問題。

所以追一下 System.Net.Mail 的 Source Code 會發現,如果自己處理掉編碼換行這段,System.Net.Mail 就會以我們處理過的原封不動丟出去。

雖然這邊註解是說會 re-encode before sending ,但是再往 DecodeHeaderValue 裡面看,會發現,他只處理 Base64 編碼過的,如果是又做過 75 個字元切段又做 Base64 的話,他就會直接放棄 re-encode 。

用 ? 去切字串,如果切出來不是  5 個,就放棄。( MimeBasePart.cs )

所以,如果我們自己處理有考慮中文字的 75 個字元切段後再 Base64 編碼的話,應該就可以解決這個問題。

private string folding(string input)
        {
            string tempInput = input;
            string result = "";
            const int f = 37; // 一個字一律算兩個 bytes 最長只能 75 所以 75/2 https://www.ietf.org/rfc/rfc2047.txt
            for (int i = 0, len = tempInput.Length; i <= len; i += f)
            {
                string x = tempInput.Substring(i, (i + f >= len ? len - i : f));
                result += string.Format(@"=?UTF-8?B?{0}?=", Convert.ToBase64String(Encoding.UTF8.GetBytes(x)));
            }
            if (result.Split("?".ToCharArray()).Length == 5) result = result + "=?UTF-8?B??="; // 只切到一次還會會被解回去,所以補一個空的
            return result;
        }

2013年3月29日

[Visual Studio 2012 Express] 開啟 *.config 檔案時,發生 "Value does not fall within the expected range" 的決解方式

是情是這樣發生的,
我有一個自己測試用的專案,放在 SkyDrive 自動同步的目錄中,
在我的兩台電腦中,他很方便,可以自動的幫我同步,
有一天,我改完程式,把 Notebook 蓋起來直接下班,
 Notebook 打開後,發現他當機重開,
之後再開起這個專案裡的 *.config 檔的時候,他就一直賞我下面這個訊息。










關鍵字搜尋了一下,
都是說要還原 Visual Studio 的設定,但,這不合理!
因為我別的專案是正常的,只有這個怪怪的。

後來找到有人有提供的解決方法:
http://forums.asp.net/post/5138757.aspx

沒錯!就是砍掉 *.suo 這個隱藏檔就好了。
這個檔案會儲存上次開啟專案時的一些狀態,
例如中斷點的設定,開了哪些程式 ... 等等。
推測,應該是因為不正常關機,造成 *.suo 損壞所導致的。


很多時候,刪掉 *.suo 、 *.user 可以決解一些問題,
所以我一向都建議不要把這後副檔名的檔案 commit 到版本控管的 Server 上。



2013年3月21日

[.Net] 決解 Visual Studio 2012 Express NuGet 無法載入的問題

不知道有沒有人遇過這樣的問題,反正我是遇到了 Orz
安裝 Visual Studio 2012 Express 一切正常,
但是,
開起已經有使用 NuGet 的專案時,出現:
未正確載入套件 'NuGet.Tools.NuGetPackage, NuGet.Tools ......'











加入一個新的專案有用到 NuGet 的時候會出現:
這個範本嘗試載入元組件 'NuGet.VisualStudio.Interop ......'








以上是發病的症狀,
我安裝的環境是 Windows Server 2012 Evaluation 英文版,
加 Visual Studio 2012 Express (Web、Desktop、Phone SDK),
不管我怎麼移除再重新加入都沒用,






後來就手動在 command line 下執行
vsixinstaller /uninstall:NuPackToolsVsix.Microsoft.67e54e40-0ae3-42c5-a949-fddf5739e7a5
執行完成後會出現以下的畫面:












咦 ~ 一次移除三個,推想這案情不單純,因為之前移除的時候都只有針對 for Web 的版本做的,我猜有可能是因為安裝時,不知道什麼原因,造成他們彼此之間不一致所導致的問題。

"NuPackToolsVsix.Microsoft.67e54e40-0ae3-42c5-a949-fddf5739e7a5"
這串 ID 可以從:

C:\Program Files (x86)\NuGet\Visual Studio 2012\NuGet.Tools.vsix

這個檔案裡面取得,先把 NuGet.Tools.vsix 的副檔名改成 .zip 再解壓縮後,
裡面的 extension.vsixmanifest 檔案中可以看到






最後,要再把 NuGet.Tools.vsix 安裝回來,
只要在 Command Line 下,上述的目錄中執行以下命令即可。
vsixinstaller NuGet.Tools.vsix

2012年12月3日

[iCalendar] 如何用 .ics 檔預約或更新 Outlook 行事曆

細節要參考 RFC2445, 2446, 2447 關於 VEVENT 的設定

RFC 2446:

iCalendar Transport-Independent Interoperability Protocol (iTIP)
specifies how calendaring systems use iCalendar objects
to interoperate with other calendar systems. It does so in a general
way so as to allow multiple methods of communication between systems.
Subsequent documents specify interoperable methods of communications
between systems that use this protocol.

iTIP 在描述的是行事曆與行事曆之間利用 iCalendar objects 的溝通方式,
舉例:
A 行事曆的 User PUBLISH 一個 VEVENT 給 B 行事曆的某個 User。
A 行事曆的 User REQUEST 一個 VEVENT 給 B 行事曆的某個 User 更新先前 PUBLISH 的 VEVENT。
B 行事曆的 User COUNTER (改變的建議)一個 VEVENT 給 A 行事曆的召集人。

而這邊的需求比較簡單,我們只需要統一的一個召集人,發出會通知(或更新)給所有參與人即可,
所以只需要用到 VEVENT REQUEST ,

一個 VEVENT REQUEST 的 .ics 格式如下:

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//RDU Software//NONSGML HandCal//EN
METHOD:REQUEST
BEGIN:VEVENT
DESCRIPTION:描述寫這邊
DTSTART:20121225T080000
DTEND:20121225T170000
DTSTAMP:20121129T093257
SEQUENCE:1
SUMMARY:標題寫這邊
UID:guid
STATUS:CONFIRMED
ORGANIZER:mailto:your@mail
END:VEVENT
END:VCALENDAR


基本上如果只要發佈(PUBLISH),就不需要用 ORGANIZER(rfc2446上說需要,但測試結果可有可無),
但 PUBLISH 不能更新原有的行事曆,
如果要更新就要用 REQUEST ,用 REQUEST 就要有 ORGANIZER。
要更新一個原有的行事曆,
必須要注意以下幾點:
1. UID:唯一識別代碼,前者和後者要一致
2. DTSTAMP: 產生 ics 的時間後者要比前者大
3. SEQUENCE: 要遞增,一樣後者要比前者大( SEQUENCE 從 1 開始,往後遞增)
4. ORGANIZER: 要填入符合 email 格式的內容

以上四點在 microsoft outlook 2007 中,2 和 3 有檢查後者一定要比前者大,
第 4 項貝沒有檢查一定要一樣(因為可以變更召集人),
但是一定要有 email 格式的內容,
這裡要注意召集人如果是自己(沒有設召集人,outlook預設是自己)的話,
就沒辦法更新( 這個超重要,試了很久才試出來 XD )。



METHOD 的部份定義在: http://tools.ietf.org/html/rfc2446#page-7

The ITIP methods
Method Description
PUBLISH Used to publish a calendar entry to one or more Calendar Users. There is no interactivity between the publisher and any other calendar user. An example might include a baseball team publishing its schedule to the public.
REQUEST Used to schedule a calendar entry with other Calendar Users. Requests are interactive in that they require the receiver to respond using the Reply methods. Meeting Requests, Busy Time requests and the assignment of VTODOs to other Calendar Users are all examples. Requests are also used by the "Organizer" to update the status of a calendar entry.
REPLY A Reply is used in response to a Request to convey "Attendee" status to the "Organizer". Replies are commonly used to respond to meeting and task requests.
ADD Add one or more instances to an existing VEVENT, VTODO, or VJOURNAL.
CANCEL Cancel one or more instances of an existing VEVENT, VTODO, or VJOURNAL.
REFRESH The Refresh method is used by an "Attendee" to request the latest version of a calendar entry.
COUNTER The Counter method is used by an "Attendee" to negotiate a change in the calendar entry. Examples include the request to change a proposed Event time or change the due date for a VTODO.
DECLINECOUNTER Used by the "Organizer" to decline the proposed counter-proprosal.



另外關於 content type ,截錄一下rfc2447的說明:

2.4 Content Type
   A MIME body part containing content information that conforms to this
   document MUST have an [RFC-2045] "Content-Type" value of
   "text/calendar". The [RFC-2045] "Content-Type" header field must also
   include the type parameter "method". The value MUST be the same as
   the value of the "METHOD" calendar property within the iCalendar
   object.  This means that a MIME message containing multiple iCalendar
   objects with different method values must be further encapsulated
   with a "multipart/mixed" MIME entity. This will allow each of the
   iCalendar objects to be encapsulated within their own "text/calendar"
   MIME entity.


2012年11月8日

[IIS] URL Rewrite 設定備忘

備忘:
我有一個網站,網站內容是純 html、js 組成的,但 js 會呼叫 services 做事,
我們希望 services 可以被 hosted 在別的 server 上,但我們同時也希望,
js 裡面在寫呼叫 services 的事,不需要管 services 的 server 在哪裡。
於是我們在這個網站上,設了一個反向 Proxy 做 URLRewrite ,
把特定的路徑 request 都導向另一台 Server 。

^s/(.*) 表示 s 這個目錄所以有網址都要 rewrite 。
("^"是指一開始,因為後面馬上接 "/",所以就是 "s" 這個目錄,

圖二中 {R:1} 表示上面表示式中 "(.*)" match 到的字串,{R:0}則表示含 "s/"。
(圖一)
(圖二)

參考資料:http://www.microsoft.com/taiwan/technet/iis/expand/URLRewrite.aspx



2012年10月9日

[EasyFlow] 增加TipTop XML 傳來之欄位


原因:
   TipTop 的請購單,備註是放在單身中,USER 反映簽核時不夠明顯,也無法輸入太多字

改善:
1.在 TipTop APMT420 中的自訂欄位,新增一欄備註( pmkud01),設定此欄位要傳到 EasyFlow

2.打開此表單的 EasyFlow XML檔 (路徑 EFNET \ WS \ EFNETService \ TTXMLDoc \ Draw \ apmt420.xml )
       在<Grid name="gr5261" width="52" height="7">的最後插入
     
<Label text="備註" posY="0" posX="69" gridWidth="8" sizePolicy="dynamic"/>
<FormField name="pmk_file.pmkud01" colName="pmkud01" sqlType="VARCHAR(255)" fieldId="999" sqlTabName="pmk_file"
      tabIndex="999">
<ButtonEdit width="10" action="controlp" image="zoom" posY="0" posX="81" gridWidth="12" scroll="1"
      sample="MMMMMM000000" comment="備註[pmkud01]"/>
</FormField>


3. 修改此EasyFlow表單的HTML(路徑 EFNET \ src \ TEI \ TEIAPMT420)
         在TABLE的最下面新增

<tr>
<td width="90" id="pmkud01_1" nowrap="true" align="right" class="normalFormCaption">備註</td><td nowrap="true" width="100">
<table style="margin:0px;padding:0px;" border="0" cellspacing="0" cellpadding="0">
<tr>
<td><span id="pmkud01_2" class="normalSpan"></span></td>
</tr>
</table>
</td>
</tr>

成果: