發表文章

如何透過 C# 類別庫讀取 Web.config 或 App.config 的參數設定值

圖片
我們經常會需要在應用程式中宣告一些參數,好讓我們的程式在不用重新編譯的情況下隨時變更參數設定值,而這樣的機制老早就內建在 .NET 之中。今天我將分享幾個常見的使用案例與範例程式,教大家如何規劃 C# 類別庫 (Class Library) 的設定檔,以及如何從 ASP.NET 應用程式 ( 包含 Web Form 與 MVC )、主控台應用程式 (Console Appliation) 與 Windows Form 應用程式正確設定 app.config 或 web.config 設定檔,以變更類別庫中參數的預設值。 讀取 web.config 設定檔的 AppSettings 與 ConnectionStrings 參數 如果你的 C# 類別庫 (Class Library) 所讀取的參數來源只有 ASP.NET 應用程式的話,那麼你可以參考以下說明進行設定。 我們先建立兩個預設專案,一個是 ASP.NET MVC 專案 ( WebApplication1 ),另一個是類別庫專案 ( ClassLibrary1 )。 假設我們希望 ClassLibrary1 類別庫專案可以讀取 WebApplication1 專案中 Web.config 裡面的 appSettings 設定值,這裡我們就以 ClientValidationEnabled 參數為例,如下圖示: 接著,如果我們直接引用 System.Configuration 命名空間,你可以從該命名空間下取得 ConfigurationSettings 類別,並透過該類別取用 AppSettings 屬性,這個屬性是一個字典型別,主要就是用來讀取 Web.config 設定檔中的  <appSettings>  參數資料。 不過,你可以發現到上圖第 17 行有個警告訊息,從「錯誤視窗」中可以看到以下錯誤: 警告    1     'System.Configuration.ConfigurationSettings.AppSettings' 已過時 : ' This method is obsolete , it has been replaced by ...

ASP.NET 5 Starter Web 專案內建的 NPM 設定檔 package.json 問題解決

圖片
之前一直沒有花時間去了解 npm ( Node 套件管理員 ) 的各種用法,尤其是  npm install --save 與 npm install --save-dev 的差異 ,今天再嘗試的時候,發現在我的本機電腦一直試不出這兩個命令有任何差異,套件都可以裝,但設定檔一直無法正確寫入,這種鬼打牆的事情,趁著這次年節假期徹底放鬆的時刻,終於被我抓到原來就是  package.json  這個檔案在搞鬼,欲知詳情,請繼續看下去。 由於 ASP.NET 5 / ASP.NET MVC 6 新的專案架構已經確定跟  bower ,  npm  整合,所有跟前端有關的套件都將改用  bower ,  npm  進行安裝與管理,因此原本由 NuGet 管理的那些前端套件,都將改用 npm 與 bower 進行套件管理,一些前端常見的工具,例如最小化(minification)與壓縮合併(bundling)也都將改由 grunt 與 gulp 等工具進行管理,而這些工具也都是透過 npm 來進行安裝。 我們先開啟 Visual Studio 2015 開發工具,新增一個新的 ASP.NET Web Application 專案,專案範本我們選擇 ASP.NET 5 Starter Web,如下圖示: 從方案總管中你可以看見 Dependencies 節點裡面有兩個分類,分別是 Bower 與 NPM 這兩個分類。 Bower 分類下的套件,被定義在專案根目錄下的  bower.json  檔案裡 NPM 分類下的套件,則是被定義在專案根目錄下的  package.json  檔案之中 你可以從 Visual Studio 方案總管中 移除套件 ,不過 安裝套件 就要靠你自己打指令了。 我先來示範如何用  bower  額外安裝  modernizr  與  respond-minmax  套件,這兩個套件都是以前在 ASP.NET MVC 5 專案範本中有出現的,但在 ASP.NET 5 Starter Web 卻被移除的。 開啟 Packag...

如何在現有 ASP.NET MVC 5 專案上加入 ASP.NET Web API

如果你已經建立好一個 ASP.NET MVC 5,而又突然想要加入 ASP.NET Web API 2 的相關套件與設定檔,你可以參考本篇文章解說的 SOP 進行設定。所有步驟也都以 Git 進行版控,各位可以到  https://github.com/doggy8088/MVC5_Add_WebAPI  查閱 每個步驟的變更紀錄 。 1. 先將 ASP.NET MVC 5 升級到最新版,並檢查 web.config 中的  <runtime>  設定 Update-Package Microsoft.AspNet.Mvc 在  web.config  檔案中先找到以下設定 < dependentAssembly > < assemblyIdentity name ="System.Web.Mvc" publicKeyToken ="31bf3856ad364e35" /> < bindingRedirect oldVersion ="1.0.0.0- 5.2.2 .0" newVersion =" 5.2.2 .0" /> </ dependentAssembly > 然後修改成正確的 ASP.NET MVC 5 版本編號 (可參考  packages.config  中的版本號) < dependentAssembly > < assemblyIdentity name ="System.Web.Mvc" publicKeyToken ="31bf3856ad364e35" /> < bindingRedirect oldVersion ="1.0.0.0- 5.2.3 .0" newVersion =" 5.2.3 .0" /> </ dependentAssembly > 2. 安裝 ASP.NET Web API 相關套件 ...

API Controller 寫在哪裡?如何命名?

Web API Controller 通常也和一般 Controller 一樣放在 ASP.NET MVC 專案的 Controller 目錄下。可是如果已經有 UserController,又需要提供 Web API 版本的 UserController,就得避開名稱衝突的問題。 一種作法是用命名來區隔,例如 UserController 和 UserApiController。後者代表 Web API 版本的控制器類別。如此命名的話,前端存取 Web API 時的 URI 就會類似 http://HostName/AppName/api/UserApi/。 [操作提示]   新增一個 API Controller:Solution Explorer \ 應用程式專案 \ Controllers 資料夾點右鍵,Add \ Controller...,在新開啟的 Add Controller 對話窗中,輸入 Controller name,選擇 Template(可用 Empty API controller 或其他與 API controller 有關的樣板)。 另一種作法是在 Controller 目錄下建一個 Api 子目錄,把所有 API Controller 放在裡面。於是,放在 Controller\Api 目錄下的控制器類別的命名空間預設會加上一層 "Api",所以不至於有名稱衝突的情形。這辦法挺好。 還有一種選擇,是把 Web API 放在 Areas 裡面。這種方式可能會需要額外寫一些程式碼來設定 routing。 資料來源:  https://www.huanlintalk.com/2013/01/aspnet-web-api-and-json.html

將 REST Web Service 變更為使用 Action-Based Routing 方式處理路由

在 Tip 2 的圖中,紅色框住的 URI 是要順便指出,這個畫蛇添足版的 Web API 方法名稱是 HandMadeJson,它和先前的 Get() 一樣是 TestJsonController 的成員。 可是如果沒有額外動手腳,用戶端在存取 http://HostName/api/TestJson/HandMadeJson 這樣的 URI  時,仍然會由預設的 Get 方法來服務,而不會派送給 HandMadeJson。這是 routing 設定的緣故,把 App_Start\WebApiConfig.cs 裡面的 Register 方法稍微改一下就行了: public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { action = RouteParameter.Optional, id = RouteParameter.Optional } ); var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml"); config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType); } } 原本的 MapHttpRoute() 呼叫所傳入的 routeTemplate 參數是 "api/{controller}/{id}",現在只是在中間多加了一個 "action" 而已。這種 routing 方式叫做 ...

使用 Request.CreateResponse() 來建立回應內容

我們當然可以在 Web API 方法中利用 Json.NET 來將物件序列化成 JSON 字串,但這種手動的方式有個缺點:我們的 API 也就只能固定傳回 JSON,而無法由用戶端發送的 HTTP 請求的 Accept 標頭來自動傳回對應之序列化格式。 如果要回傳的內容是自訂型別的物件,而且希望使用 ASP.NET Web API 內建的 content-negotitation 機制,有個方法很好用: Request.CreateResponse()  。以下是個簡單範例: [HttpGet] public HttpResponseMessage Get() { var result = new { UserName = "Michael", City = "Taipei" }; return Request.CreateResponse(HttpStatusCode.OK, result); } 這寫法要比自己手動序列化物件來得簡潔多了。 資料來源:  https://www.huanlintalk.com/2013/01/aspnet-web-api-and-json.html

手動傳回 JSON 或任何格式的內容

有時候,Web API 的傳回結果不是 JSON,例如我們可能需要傳回一些純文字,甚至圖片或任何二進位檔案。此時就會需要跳過自動序列化的機制,使用我們自行建立的內容來傳回前端。 碰到這種情形,我們可以將 Web API 方法的回傳型別宣告為 HttpResponseMessage。參考以下範例: using System.Collections.Generic; using System.Net.Http.Headers; using System.Web.Http; using NewtonSoft.Json; namespace MvcAppDemo1.Controllers.Api { public class TestJsonController : ApiController { [HttpGet, HttpPost] // 讓此方法可同時接受 HTTP GET 和 POST 請求. public HttpResponseMessage HandMadeJson() { var data = new Dictionary<string, string>() { // 略 } string json = JsonConvert.SerializeObject(data); var result = new HttpResponseMessage(HttpStatusCode.OK); result.Content = new StringContent(json); result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); return result; } } } 由於是傳回文字內容,所以這裡是用 StringContent 來建立內容物件。 透過這種方式,即使沒有像 [Tip 2] 的額外處理,我們的 Web API 仍然可以傳回 JSON 字串,甚至任何格式的內容。...