2009年5月26日 星期二

The control with ID 'endCalendarExtender' requires a ScriptManager on the page. The ScriptManager must appear before any controls that need it.

當 Web Application 由 ASP.NET 2.0升級到 3.5 後,原本一些網頁有使用 ASP.NET AJAX 1.0 的,全部掛了。錯誤訊息如下

The control with ID 'endCalendarExtender' requires a ScriptManager on the page. The ScriptManager must appear before any controls that need it.

為什麼呢?原來 Ajax control toolkit (ACT) 有許多版本,我使用的是搭配 ASP.NET AJAX 1.0 的版本。之後,微軟推出 ASP.NET 3.5 後,Ajax control toolkit 也出了搭配 3.5 的元件。但我仍未升級 ACT, 仍舊使用舊版的ACT。

因此,執行的過程中,舊版的 Ajax control toolkit 要找 ASP.NET AJAX 1.0 中的 ScriptManager,當然找不到。

此時,需要指定 runtime 的 相容性版本。如下。

 <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35"/>
        <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35"/>
        <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>
請參考這裡

2009年5月21日 星期四

各大 ISP 對海外連線頻寬

昨天我家的有線電視打來,想要我使用他們的光纖。
費率只需6xx 元,比起中華電信的 9xx 省下不少。

但是,對於該有線電視的品質,我向來有疑慮。
我問了一個問題:對外頻寬呢?我常連美國呢!

他一時之間似乎呆住了。一會兒回答:我們是連到台灣固網的,對海外頻寬沒問題。

我回答,我記得海外頻寬,有差到20倍之多呢!

但我也是靠記憶,而人的記憶是不可靠的。

查了一下 http://map.twnic.net.tw/main04.php,在2002 年10月,台固連美國是 223.68 mbps, 中華電信是 2888.83 mbps,差了10倍。

到了今年 4 月,台固連美國是 4000 mbps, 中華電信是 77325 mbps,差了19倍。愈差愈多。

雖然這不是唯一的標準,但常連線到美國的我,卻是不得不考慮的事。
如果你只是連連國內的網站,那連外頻寬就不是太大的問題。
此外,各家ISP的使用戶數也是個問題,但這個數字比較難找到。

你家是用哪一個 ISP 呢?

附圖:2009年4月的中華電信頻寬。

image

2009年5月20日 星期三

VS2010 Beta 1 可以在微軟訂閱下載了

過了這麼久,終於可以下載了。

http://msdn.microsoft.com/en-us/subscriptions/default.aspx

2010 又是微軟的大年。這一年,要出

  1. Win 7
  2. VS2010
  3. Office 14
  4. Windows Server 2008 R2

2009年5月19日 星期二

MOSS 2007: 核准流程的結果

在MOSS 2007 上,有個預設的核准流程。
客製化時,需要取得文件庫的「核准」結果。
但取得後,卻是字串的 17 ??

上網查了一下,該值可能如下。

// In Progress – 2
//Complete – 5
//Canceled – 15
//Approved – 16
//Rejected - 17

public static string GetApprovalDesc(string approval)
    {
      switch (approval)
      {
        case "2":
          return "InProgress";
        case "5":
          return "Complete";
        case "15":
          return "Cancled";
        case "16":
          return "Approved";
        case "17":
          return "Rejected";
        default:
          return approval.ToString();
      }
    }

這個結果,並非我最想要的。因為「核准」流程的對象,可以自己。
這一點實再不能接受。
下一次,需要找一個送審者與審核者的對照。

2009年5月14日 星期四

Silverlight 2: Datagrid 無法 Binding Anonymous type

在初次使用 Silverlight 2 Datagrid 元件後,覺得還可以。但在 databind 時,就無法像 asp.net 的 GridView 可以直接 format 資料格式了。

因此,我偷偷用了 anonymous type,做為資料轉格式的方式。
但失敗了。

寫了一個測試的 sample 如下。

Page.xaml

<UserControl xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"  x:Class="SilverlightApplication2.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="400" Height="300">
  <Grid x:Name="LayoutRoot" Background="White">
    <data:DataGrid x:Name="dgNames" AutoGenerateColumns="True" Loaded="dgNames_Loaded"></data:DataGrid>
  </Grid>
</UserControl>

Page.xaml.cs

 

using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;

namespace SilverlightApplication2
{
  public partial class Page : UserControl
  {
    public Page()
    {
      InitializeComponent();
    }

    private void dgNames_Loaded(object sender, RoutedEventArgs e)
    {
      List<string> myNames = new List<string> { "Charles", "Julia", "TingYu" };

      var q = from n in myNames
              select new
              {
                n
              };

      dgNames.ItemsSource = q.ToList();
    }
  }
}

結果出現錯誤

Webpage error details

User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.5.21022; .NET CLR 1.1.4322; .NET CLR 3.5.30729; .NET CLR 3.0.30618; MS-RTC LM 8; OfficeLiveConnector.1.3; OfficeLivePatch.0.0)
Timestamp: Thu, 14 May 2009 09:01:40 UTC

Message: Sys.InvalidOperationException: ManagedRuntimeError error #4004 in control 'Xaml1': System.MethodAccessException: <>f__AnonymousType0`1.get_n()
   at System.Reflection.MethodBase.PerformSecurityCheck(Object obj, RuntimeMethodHandle method, IntPtr parent, UInt32 invocationFlags)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
   at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index)
   at System.Windows.Data.BindingExpression.ConnectToSource(Int32 index)
   at System.Windows.Data.BindingExpression.DataContextChanged(Object o, DataContextChangedEventArgs e)
   at System.Windows.FrameworkElement.OnDataContextChanged(DataContextChangedEventArgs e)
   at System.Windows.FrameworkElement.OnTreeParentUpdated(DependencyObject newParent, Boolean bIsNewParentAlive)
   at System.Windows.DependencyObject.UpdateTreeParent(IManagedPeer newParent, Boolean bIsNewParentAlive)
   at MS.Internal.FrameworkCallbacks.PeerTreeUpdate(IntPtr parentElement, IntPtr childElement, Byte bIsParentAlive)
Line: 453
Char: 17
Code: 0
URI: http://localhost:21320/ScriptResource.axd?d=v7RAdeBdTb1UtK_ZSZJcchuxmNZp7aBSXoH0iSyCwic_hoCgZtj9xlxZTDuqBow-wrdCLEr4fnN6W6pMvdTnOQ2&t=ffffffffafbd6209

 

天啊!無法不利的 LINQ 竟然在 Silverlight 2.0 敗下陣來。

看來是 Anonymous type 不太行了。因此改成下方的程式即可。斜粗體字的部份即是修改的部份。注意到 TempData 必須是 public。

Page.xaml.cs (Updated)

using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;

namespace SilverlightApplication2
{
  public partial class Page : UserControl
  {
    public Page()
    {
      InitializeComponent();
    }

    private void dgNames_Loaded(object sender, RoutedEventArgs e)
    {
      List<string> myNames = new List<string> { "Charles", "Julia", "TingYu" };

      var q = from n in myNames
              select new TempData
              {
                Name = n
              };

      dgNames.ItemsSource = q.ToList();
    }

    public class TempData
    {
      public string Name { get; set; }
    }
  }
}
這樣就正常了。
image 

SandCastle 的安裝及使用

以往在 Visual Studio 2003 時,會使用 NDoc 來製作原始碼的說明文件。但這個 Ndoc已經許久沒出新版啦!
現在則被 SandCastle 所取代!

以下是安裝及使用過程

安裝 SandCastle

這裡 下載後安裝之。SandCastle 是一個 command line 的工具,因此使用起來特別難過。

安裝 Sandcastle Help File Builder

Sandcastle Help File Builder 是一個 Sandcastle 的 UI 輔助工具。這才是我們最常用的。以下簡稱 SHFB

在 C# 原始碼寫說明

這一點不必再說明了吧!如果需要複習,請見 XML Documentation

打開 xml output

專案在 build 時,預設不會寫出 xml document。必須到每個專案下設定 property。如下圖。

image

執行 Sandcastle Help File Builder GUI

執行 SHFB 後,首先在右方的 Project Explorer,選取 Documentation Sources 上按右鍵,點擊 Add Documentation Source….,將 solution 加入。

image

再來設定一些基本的資訊

image

製作

最後,就開始製作啦!(工具列)

image

Add Reference

通常,我們會用一些特別的元件,如 SilverLight 等,或在 GAC 上的 assembly。這些不在 solution 目錄,或 bin 目錄下的元件預設是抓不到說明的。此時,很快地會發生錯誤。如下

MREFBUILDER : error : Unresolved assembly reference: System.Windows (System.Windows, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e) required by ProjectStatisticsSL
    Last step completed in 00:00:04.6335
-------------------------------

SHFB: Error BE0043: Unexpected error detected in last build step.  See output above for details.

因此,需要在 Project Explorer 上新增 Reference

image 

那要增加什麼呢?看原來的 assembly 資訊。如下圖,將System.Windows對應的 assembly Path 加入即可

image

image

看成果

按一下工具列上的放大鏡。就會看到文件囉!

image

2009年5月12日 星期二

電子發票有「毒」! 宅宅族網購需當心 !? 亂報!

今日的標題:電子發票有「毒」! 宅宅族網購需當心

http://tw.news.yahoo.com/article/url/d/a/090511/17/1jaez.html

我去查了一下 Trend 的新聞稿,http://tw.trendmicro.com/tw/about/news/pr/article/20090508090023.html ,其實與國內的電子發票完全無關。

該新聞稿中的標題為「新種發票垃圾郵件假藉亞馬遜Amazon之名散發 點選附件即中毒」,內容也只是陳述病毒假籍發票名義傳送zip附件,內含木馬而已。

而不明究裡的記者及報社就將該「電子郵件」、「發票」,聯想成「電子發票」,並與國內的電子發票機制混在一起談,還與網購牽聯在一起,目的是為了造就話題

例如:該病毒也可假籍「H1N1最新發展」等其它名義傳播。

WCF 設定:此服務的安全性設定需要 'Anonymous' 驗證,但裝載此服務的 IIS 應用程式未啟用該驗證。

老問題了。在IIS 7 又發生了如下的錯誤。

'/' 應用程式中發生伺服器錯誤。

此服務的安全性設定需要 'Anonymous' 驗證,但裝載此服務的 IIS 應用程式未啟用該驗證。

描述: 在執行目前 Web 要求的過程中發生未處理的例外情形。請檢閱堆疊追蹤以取得錯誤的詳細資訊,以及在程式碼中產生的位置。
例外詳細資訊: System.NotSupportedException: 此服務的安全性設定需要 'Anonymous' 驗證,但裝載此服務的 IIS 應用程式未啟用該驗證。

原因

*.svc檔需要 Anonymous 來讀取,以提供 wsdl。而目錄並未提供 Anonymous 的權限。

步驟

  1. 檢查目錄是否有 Network Service 的 「讀取及執行」、「列出資料夾內容」、「讀取」的權限
  2. 檢查目錄是否有 IIS_IUsrs 的 「讀取及執行」、「列出資料夾內容」、「讀取」的權限
  3. 在 IIS Manager 上檢查目錄是否有啟用「匿名驗證」

image image

更詳的步驟,參考這裡

2011/02/09: 有時,是IIS 未註冊成功的目題,請試著執行

執行"%windir%\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\ServiceModelReg.exe" -r –y

2011/06/09: 在 dotnet V4.0,要執行"%windir%\Microsoft.NET\Framework64\v4.0.30319\ServiceModelReg.exe" –r

2012/06/06: 在 Windows 8 的 IIS 8 上,ServiceModelReg 已被取消。所得的結果只剩下

Microsoft (R) WCF/WF registration tool version 4.5.0.0
Copyright (c) Microsoft Corporation.  All rights reserved.

Administration utility that manages the installation and uninstallation of
WCF and WF components on a single machine.

[Error]This tool is not supported on this version of Windows. Administrators should instead install/uninstall Windows Communication Foundation features using the 'Turn Windows Features On/Off' dialog, or the dism command line tool.

意思是:只能使用Turn Windows Features on or of 的方式來安裝。

2009年5月7日 星期四

Windows 7 Keyboard Shortcuts

from http://on10.net/blogs/larry/Top-7-Things-to-Check-Out-in-Windows-7-RC1/ 

Keyboard shortcuts

    • Dock your windows left and right with WindowsKey+left/right arrows.
    • Win+up/down to minimize / restore / maximize.
    • Win+Shift+up/down arrows to maximize and restore vertical size.
    • Win+Shift+left/right arrows to jump windows to other monitors.
    • Win+P to change through display modes.
    • Win+1, Win+2, etc.. For launching new instance of any of the first five icons on your taskbar.
    • Win+Space to peek at your desktop.
    • Win+T will put focus on the taskbar so you can use the arrow keys to select which window or group, then hit enter.

Keyboard+Mouse shortcuts

    • Want to flick through a bunch of open Outlook windows? Control + Click on the Outlook icon in the task bar. That works for any program with multiple windows like Internet Explorer.
    • Shift+Click on a application in your taskbar to launch a new instance of it, like a web browser.
    • Shift+Right Click on a file in Windows Explorer to get an expanded Send To menu.

2009年5月6日 星期三

在 Silverlight 中使用 WCF 的心得

最近在開始才有機會使用 Silverlight. 這裡將遇到的心得寫下來,以便大家參考(當然也包括自己)
  1. Silverlight 2.0 只能使用 basicHttpBinding,尚未無法使用 wsHttpBinging。
  2. 在 Silverlight 2.0  中當作 WCF Client 呼叫 WCF Service 時,需注意到有許多特性不能使用。否則會發生則似下面的錯誤訊息。

Message: Unhandled Error in Silverlight 2 Application Unrecognized attribute 'allowCookies' in service reference configuration. Note that attribute names are case-sensitive. Note also that only a subset of the Windows Communication Foundation configuration functionality is available in Silverlight.  

其實 Visual Studio 2008 在開發時已經有提醒了,只是我沒注意到。看 config file 的 editor 畫面,有出現 blue underline 的提醒。
image

    3.  我是使用於 MOSS 的環境下,開發時會使用 http://moss/ 來存取 MOSS,而 WCF Client 在呼叫時,預設會寫成 http://moss.domain.com/ 這樣的存取方式。

<client>
 <endpoint name="BasicHttpBinding_IMyService" contract="MossServices.IMyService" binding="basicHttpBinding" address="http://epmoss.domain.com/wcf/MyService.svc" bindingconfiguration="BasicHttpBinding_IMyService" />
</client>
這樣一來,SilverLight 會以為是跨 domain 來存取 wcf,且認為是不安全的。於是又開始找 clientaccesspolicy.xml (see 讓服務可跨網域界限使用)
因此,必須手動地改成相同的 domain. 如下
<client>
  <endpoint name="BasicHttpBinding_IMyService" contract="MossServices.IMyService" binding="basicHttpBinding" address="http://epmoss/wcf/MyService.svc" bindingconfiguration="BasicHttpBinding_IMyService" />
</client>

   4.  WCF 預設無法讀取 asp.net 環境的 Context。如果需要讀取 Context,則必須做以下的改變。(參考 這裡)

第一個,是在 class 上增加[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)] 的attribute

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
  public class MyService : IMyService
  {
    public string GetCurrentSiteName()
    {
      
      SPContext context = SPContext.Current;
      var q = (from SPList i in context.Web.Lists
               select i.Description).ToArray();
      return string.Join(",", q);
    }
  }

第二,是在 Web.config 上增加下列設定 (字體放大加粗的部份)。此用意在讓wcf 環境可與 asp.net 相容外,也要讓 client side 的資訊能傳到 wcf service 來。

<system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="myBasicBinding">
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Ntlm"/>
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
    <services>
      <service behaviorConfiguration="MossWcfServiceLibrary.MyServiceBehavior"
        name="MossWcfServiceLibrary.MyService">
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration="myBasicBinding"
          contract="MossWcfServiceLibrary.IMyService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MossWcfServiceLibrary.MyServiceBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

2009年5月4日 星期一

Asp.net 執行匯入進度

顯示匯入或上傳的進度,想必是許多 asp.net 開發人員一定會遇到的問題。
以下是我的解法。

為了讓 progress bar 能跑,當然需要 jQuery.
JQuery Progress Bar 1.1 已經幫我們寫好了,我們只需要使用即可。

再來,為了讓網頁能立刻反應當下的進度,需要使用 ASP.NET Ajax 的 AJAX 之 PageMethod 功能。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Script.Services;
using System.Web.Services;
using System.Threading;

namespace WebApplication1
{
  public partial class _Default : System.Web.UI.Page
  {
    private static SlowTask slowTask = null;

    protected void Page_Load(object sender, EventArgs e)
    {

    }

    [ScriptMethod]
    [WebMethod]
    public static Progress GetTaskCurrentProgress()
    {
      int ii = Thread.CurrentThread.ManagedThreadId;
      return new Progress
      {
        CurrentCount = slowTask.CurrentCount,
        TotalCount = slowTask.TotalCount,
        Message =       string.Format("{0}/{1} : {2}", slowTask.CurrentCount, slowTask.TotalCount, 
        slowTask.GetAsyncTaskProgress())
      };
    }

    public struct Progress
    {
      public string Message;
      public int TotalCount;
      public int CurrentCount;
    }

    

    [ScriptMethod]
    [WebMethod]
    public static void RunItSync()
    {
      int ii = Thread.CurrentThread.ManagedThreadId;
      slowTask = new SlowTask(1000);
      slowTask.ExecuteAsyncTask();
    }
  }
}
Code behinds
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Script.Services;
using System.Web.Services;
using System.Threading;

namespace WebApplication1
{
  public partial class _Default : System.Web.UI.Page
  {
    private static SlowTask slowTask = null;

    protected void Page_Load(object sender, EventArgs e)
    {

    }

    [ScriptMethod]
    [WebMethod]
    public static Progress GetTaskCurrentProgress()
    {
      int ii = Thread.CurrentThread.ManagedThreadId;
      return new Progress
      {
        CurrentCount = slowTask.CurrentCount,
        TotalCount = slowTask.TotalCount,
        Message =       string.Format("{0}/{1} : {2}", slowTask.CurrentCount, slowTask.TotalCount, 
        slowTask.GetAsyncTaskProgress())
      };
    }

    public struct Progress
    {
      public string Message;
      public int TotalCount;
      public int CurrentCount;
    }

    

    [ScriptMethod]
    [WebMethod]
    public static void RunItSync()
    {
      int ii = Thread.CurrentThread.ManagedThreadId;
      slowTask = new SlowTask(1000);
      slowTask.ExecuteAsyncTask();
    }
  }
}

sample code download here.

Database Schema 的文件製作

大家都有這樣的需要,能從 Database 中製作出文件。

http://sqldoc.codeplex.com/ 就是一個了。免費,只有 source code,對於有安裝 Visual Studio 2008 的人不是問題吧。

效果還可以,可是只能作 chm 格式的,只支援 SQL 2005/2008.

有個小 bug. 只能執行一次。下一次再產生文件,記得重新再執行一次程式。

使用前,記得裝 HTML Help Workshop,才能製作 chm。

Share with Facebook