2011年6月17日 星期五

翻譯錯誤又一件

見 http://msdn.microsoft.com/zh-tw/library/system.windows.threading.dispatcherframe.aspx

execution (執行) 怎麼會翻譯成例外(exception) 呢?機器翻譯時不會翻錯字,這明顯地不是機器翻譯的,而是人去翻譯的。

image

結論

沒有人會故意犯錯,但只要是人,就很可能犯錯。(當然包括我)

可以的話,還是看原文比較好。雖然較吃力,但至少不會被誤導而不自知。

2011年6月8日 星期三

WCF Data Service 在 PUT 時發生 405 Method Not Allowed

原因

最近在使用 WCF Data Services 時,WCF Data Services Client library 使用 DELETE HttpMethod 時,發生了 HTTP Error 405.0 - Method Not Allowed 的錯誤。

SNAGHTML1d31d0e

HTTP Error 405.0 - Method Not Allowed

The page you are looking for cannot be displayed because an invalid method (HTTP verb) is being used.

解決

經過不少的測試,也試過移除IIS 7 的 WebDAV module,都不成功。最簡單的方法,是在 Web.Config 中增加下面的設定。感謝 IIS 7。

<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules>
  <remove name="WebDAVModule" />
</modules>
<handlers>
  <remove name="WebDAV" />
</handlers>
</system.webServer>

 

參考

打開 IIS 7 的壓縮功能

緣由

近來幾乎所有的 Middle Tier 的功能,微軟都是使用 IIS 來作 Host,最有名的就是WCF。如果要建置跨平台的解決方案,使用 xml + Http 幾乎是不二人選,binary 的 protocal 就把它忘了吧。

然而, xml + http 為人最為垢病的地方,就是它實在痴肥。為了讓它減肥,我不得已來 study 如何在 IIS 7 上壓縮網頁的輸出。

如下圖,我呼叫叫了一個 WebService,回傳的是 xml,但大小竟然是 1.5 MB!!這叫我如何能接受?

image

過程

Step1: 安裝Dynamic Content Compression

說實話,我已在 IIS 6 上實作過了。IIS 6 的過程實在不人道,我也不想 POST 到部落格上。而 IIS 7 就簡單許多。

首先,要了解的是 IIS 7  預設就打開了靜態內容的壓縮。不像 IIS 6預設都不壓縮。這大概與 IIS 壓縮的成熟度有關吧。

打開 IIS 7, 點到 Compression 的功能,右方出現一排字「The dynamic content compression module is not installed」,意思就是沒有安裝 dynamic content compression 這一個 module。

imageimage

使用 Programs and Features,執行左方 Menu  的 Turn Windows features on or off,並勾選「Dynamic Content Compression」,按OK建進行安裝。

imageSNAGHTML70f490

安裝完成後,再到 IIS 上執行Compress 的設定。check 一下,果然設定成功了。

image

Step 2: 設定 全機壓縮

只有安裝 dynamic content compression 模組是不夠的。IIS 此時尚不知道要對什麼動態內容作壓縮,接下來設定的就是:「告訴 IIS 什麼樣的內容要作動態壓縮」

在 IIS 上,點選 machine 名稱,執行「Configuration Editor」。

SNAGHTML82361b

選 Section : system.webServer/httpCompression,並調整「dynamicTypes」

image

按右方 Actions Pane 的 Add 連結,並輸入 application/atom+xml

image

記得完成後,要按右上的 Apply 鍵完成設定。

最後,還要重新起動 IIS

SNAGHTML8e7694

結果

再使用Fiddler 測試一下相同的網頁。Oh, My God, 1.5MB的內容壓縮過後只剩 149 KB,壓縮成原來的 10% ,省下的頻寬實在可觀。

image

2011年6月2日 星期四

TFS 的 Web 自動部署

繼上次的 TFS 建置:Coded UI 自動測試 問題後,好久好久我都沒再碰 TFS 的 Build 設定了。

這次,目的在建立 Web 的自動部署。

環境

這次的環境較為複雜。有開發機,TFS Server,Build Server,Test WebServer.

希望可以達成的需求:在開發機上要求一個 Build後,TFS Server 向 Build Server 要求啟動一個 Build。Build Server 完成 Compile 後,將 Web Application 自動部署到 Test WebServer。

過程還有些漫長,最大的原因還是「太久遠的記憶」是不可靠的。下面是我試出來的結果。

Build Definition

在 MSBuild Arguments 我設定如下

/p:DeployOnBuild=True
/p:DeployTarget=MsDeployPublish
/p:MSDeployPublishMethod=RemoteAgent
/p:CreatePackageOnPublish=True
/p:DeployIisAppPath="Default Web Site/YourApp"
/p:MsDeployServiceUrl=http://172.199.199.199/MsDeployAgentService
/p:username=administrator
/p:password=adminpassword

image

 

Build Server

Build Server 上,必須安裝了 Visual Studio 2010。我試的結果,不裝,就不會自動部署。我不知道到底我錯過了什麼環結,雖然設定了上述的 MSBuild Arguments,但就是不跑 Deploy。

安裝時,我選了 c# 與Visual Web Developer。理論上只需安裝 Visual Web Developer即可,但我不想再浪費時間試了。

image

另外,在 Visual Studio 2010 Web Application 的專案屬性上,也有一些玄機。如果有勾選「Include IIS settings as configured in IIS」或「Include application pool settings used by this Web project」的話,在 Build Server 就要安裝 IIS 並且有相同的設定。因為當 Build Server 要打包 package 時,需要讀IIS的設定。讀不到設定就會出現下面的錯誤訊息。

C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets (1657): "MapUriToIisWebServer" 工作發生未預期的失敗。 System.Runtime.InteropServices.COMException (0x80005000): 未知的錯誤 (0x80005000)  

image

此時的我,顧不得完美了,先不要勾選這兩個選項了。

Test Web Server

1 在待部署的 Web Server 上,必須安裝 Web Deployment Tool。安裝時,必須注意要選「完整」安裝。

2 安裝完畢後,需要在服務中啟動 Web Development Agent Service

image

3  Build 執行後出現下面的錯誤

Web deployment task failed.((2011/6/2 下午 05:14:42) An error occurred when the request was processed on the remote computer.)  (2011/6/2 下午 05:14:42) An error occurred when the request was processed on the remote computer. The application pool that you are trying to use has the 'managedRuntimeVersion' property set to 'v2.0'. This application requires 'v4.0'.

由於我沒有選擇要打包 IIS 的設定,部署後的應用程式是下 Default Web Site 下。Default Web Site 預設是.net framework v2.0, MSDeploy 在建立 application 時會預設同上一層的 application pool。

我的解法是直接將上一層的 Default Web Site 改用 v4.0 的 application pool。

結論

上述設定,一定還有調整優化的空間。之後有空再寫 blog好了。

雖然很麻煩,但想到之後不必再手動部署測試環境時,心裡也就舒坦了許多。

參考

危險的 HTTP method 測試

緣故

今天早上客戶寄來一封資安檢測結果,說我們維護的Web系統有漏洞。

弱點大意是:Web Server 提供了 PUT, TRACE, DELETE, CONNECT 的 Http Method. 應該關閉。

並且把這項缺失列為中等風險,寫的很厲害的樣子。「PUT method 允許用戶端上傳檔案至伺服器, DELETE method 允許用戶端將伺服器的檔案刪除. 將允許遠端攻擊者可任意上傳檔案至伺服器而置換網頁, 若攻擊者上傳惡意程式到具有執行權限的目錄, 將可達到更大的破壞.」

過程

記得我們沒有開 WebDAV 啊!為什麼寫的這麼離譜?使用 Fiddler 查一下吧!

使用 Fiddler 的 Request Builder 查開發機 IIS

image

再選到 Inspectors,看查詢的 Request 及 Response (結果)
OPTIONS 會列出該 Web Server 可使用的 Http Method.

image

結果列出來,只有一項 TRACE 是有爭議的。根據 RFC 2616 指出,這是用來 Debug 用的 Method,可能揭露出不必要的資訊。因此會被列為風險。在 Apache 上更可能被偷取 cookie。

IIS

為什麼在IIS 上 TRACE 預設是可以使用的呢?再使用 Fiddler,這次使用 TRACE 查一下吧。

image

image

這次的結果是 HTTP/1.1 501 Not Implemented (未實作)。HttpStatus 500 以上代表伺服器錯誤。

雖然有開放 TRACE 這個 Method,但一律回未實作。這妙吧。
因此,沒有漏洞。

再使用 DELETE 查一下。結果是 405 Not allowed(不允許)。這證明 IIS 上的WebDAV 果然沒有開啟。

image

結論

一看到資安檢測結果時,雖然只有這一項目,還是心裡不舒服。

看來該資安廠商是使用工具掃出來的結果。雖然只有一個 TRACE 看來符合,但把整個 PUT, DELETE, TRACE, CONNECT 全部列上去,看來比較有「價值」。

另外, IIS 為什麼要列為可用的Method,然後再回應 501 未實作呢?這裡就不深究原因了。

2011年6月1日 星期三

Enterprise Library on NuGet

NuGet 也可以直接安裝 Enterprise Library 了。

問題

舉例來說,之前在使用 Enterprise Library Exception Handling Application Block 時,需要在專案上加入下列參考

Microsoft.Practices.EnterpriseLibrary.Common
Microsoft.Practices.EnterpriseLibrary.ExceptionHandling

沒有經驗的人,很難一次引用正確。

解決方式:NuGet

Add Library Package Reference

image

安裝指定的 package

image

完成!還比想像中多了一些 dll,這些 unity 在用的 dll,什麼時候會用到我也不知道。

image

可惜的是,引用 package 並不會直接產生 .config 的設定。原因很簡單,它不知道我們要設定些什麼。

Enterprise Library 的設定太靈活了,要設定的話,還是乖乖地使用 Enterprise Library Configuration Editor 來設定吧。

2011年5月27日 星期五

在WPF 中對所有的 UserControl 作樣式設定

需求

在WPF 中如何一次對所有的 UserControl 作樣式設定呢?

第一版

在 WPF 中,要對同一個 Control 作預設的樣式設定很簡單。只需要在 App.xaml 中設定即可。

App.xaml

<Application x:Class="WpfApplication1.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
  <Application.Resources>
    <Style TargetType="UserControl">
      <Setter Property="Background" Value="Gray" />
    </Style>
  </Application.Resources>
</Application>

 

在 Visual Studio 中,可以在 designer 看到 usercontrol 的樣式套用了指定的樣式,看起來是可以的樣子哦!(當然沒這麼簡單,不然就不用寫這一篇了)

image

執行起來畫面就是沒有套用到。

image

程式的部份,請看附件的 WpfApplicatioin1 這個專案。

第二版

不信邪的我,稍稍改動了一下,讓樣式直接指定 UserControl1。這樣就可以套用樣式了。

<Application x:Class="WpfApplication2.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfApplication2"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
    <Style TargetType="{x:Type local:UserControl1}">
      <Setter Property="Background" Value="Gray" />
    </Style>
  </Application.Resources>
</Application>

這樣子只能套用到指定的 UserControl1,而非所有的樣式。原因是:樣式雖然可以像「繼承」樣子套用到指定的 Type,但不是繼承出來的 Type 都可以套用父類別的樣式。

程式的部份,請看附件的 WpfApplicatioin2 這個專案

第三版

這一版,自已加上了一個自訂的 MyUserControl 並繼承自 UserControl。之後,所有的 UserControl 都改繼承自訂的 MyUserControl。

在 App.xaml 中,樣式使用 BaseOn 這個關鍵。

<Application x:Class="WpfApplication3.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfApplication3"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
    <Style TargetType="UserControl" x:Key="baseStyle">
      <Setter Property="Background" Value="Gray" />
    </Style>
    <Style TargetType="{x:Type local:MyUserControl}" BasedOn="{StaticResource baseStyle}" />
  </Application.Resources>
</Application>

滿心歡喜地以為這樣萬事 OK 了,結果還是失敗。使用 Snoop 來查一下,Style 並沒有值。

image

程式的部份,請看附件的 WpfApplicatioin3 這個專案

最後版本

不知道這是不是 bug。結果還是動用了 code behind 來解決事情。

public class MyUserControl : UserControl
{
public MyUserControl()
{
  this.Style = this.FindResource("baseStyle") as Style;
}
}

使用 Snoop 來看,終於有套用到 style 了

SNAGHTML27d2b2c

程式的部份,請看附件的 WpfApplicatioin4 這個專案

結論

這是 WPF 4 的 bug 嗎?不知道。只知道浪費了2小時的時間。

Share with Facebook