[索引頁]
[源碼下載]
返璞歸真 asp.net mvc (11) - asp.net mvc 4.0 新特性之自宿主 Web API, 在 WebForm 中提供 Web API, 通過 Web API 上傳檔案, .net 4.5 帶來的更方便的非同步作業
作者:webabcd
介紹
asp.net mvc 之 asp.net mvc 4.0 新特性之 Web API
- 自宿主 web api
- 宿主到 iis,通過 WebForm 提供 web api 服務
- 通過 Web API 上傳檔案
- .net 4.5 帶來的更方便的非同步作業
樣本
1、自宿主 Web API 的 demo
WebApiSelfHost/Program.cs
/* * 自宿主 web api 的 demo * * 測試地址:http://localhost:123/api/hello */using System;using System.Collections.Generic;using System.Linq;using System.Net.Http;using System.Text;using System.Web.Http;using System.Web.Http.SelfHost;namespace WebApiSelfHost{ // web api public class HelloController : ApiController { public string Get() { return "hello: webabcd"; } } class Program { static readonly Uri _baseAddress = new Uri("http://localhost:123/"); static void Main(string[] args) { HttpSelfHostServer server = null; try { // 配置一個自宿主 http 服務 HttpSelfHostConfiguration config = new HttpSelfHostConfiguration(_baseAddress); // 配置 http 服務的路由 config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); // 建立 http 服務 server = new HttpSelfHostServer(config); // 開始監聽 server.OpenAsync().Wait(); // 停止監聽 // server.CloseAsync().Wait(); Console.WriteLine("Listening on " + _baseAddress); Console.ReadLine(); } catch (Exception ex) { Console.WriteLine(ex.ToString()); Console.ReadLine(); } } }}
2、示範如何在 WebForm 中提供 web api 服務
Global.asax.cs
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Routing;using System.Web.Security;using System.Web.SessionState;using System.Web.Http;namespace WebApiWebFormHost{ public class Global : System.Web.HttpApplication { protected void Application_Start(object sender, EventArgs e) { // 配置路由 RouteTable.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); } }}
HelloController.cs
/* * 宿主到 iis,通過 WebForm 提供 web api 服務 * * 測試地址:http://localhost:4723/api/hello */using System;using System.Collections.Generic;using System.Data;using System.Linq;using System.Net;using System.Net.Http;using System.Web.Http;namespace WebApiWebFormHost{ public class HelloController : ApiController { public IEnumerable<string> Get() { string[] names = { "webabcd", "webabcd2", "webabcd3" }; return names; } }}
3、示範如何通過 web api 上傳檔案
WebApiWebFormHost/UploadFileController.cs
/* * 通過 web api 上傳檔案 */using System;using System.Collections.Generic;using System.Linq;using System.Net;using System.Net.Http;using System.Threading.Tasks;using System.Web.Http;namespace MVC40.Controllers{ public class UploadFileController : ApiController { public async Task<string> Post() { // 檢查是否是 multipart/form-data if (!Request.Content.IsMimeMultipartContent("form-data")) throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); // 設定上傳目錄 var provider = new MultipartFormDataStreamProvider(@"c:\\temp"); // 接收資料,並儲存檔案 var bodyparts = await Request.Content.ReadAsMultipartAsync(provider); string result = ""; // 擷取表單資料 result += "formData txtName: " + bodyparts.FormData["txtName"]; result += "<br />"; // 擷取檔案資料 result += "fileData headers: " + bodyparts.FileData[0].Headers; // 上傳檔案相關的頭資訊 result += "<br />"; result += "fileData localFileName: " + bodyparts.FileData[0].LocalFileName; // 檔案在服務端的儲存地址,需要的話自行 rename 或 move return result; } }}
WebApiWebFormHost/UploadDemo.cshtml
@{ Layout = null;}<!DOCTYPE html><html><head> <title>調用 web api 上傳檔案的 demo</title></head><body> @using (Html.BeginForm("UploadFile", "api", FormMethod.Post, new { enctype = "multipart/form-data" })) { <input type="text" id="txtName" name="txtName" value="webabcd" /> <div>please select a file</div> <input name="data" type="file" multiple /> <input type="submit" /> }</body></html>
4、.net 4.5 帶來的更方便的非同步作業
AsyncController.cs
/* * 示範如何利用 .net 4.5 的新特性實現非同步作業 * * 什麼情境下需要非同步作業? * 在因為磁碟io或網路io而導致的任務執行時間長的時候應該使用非同步作業,如果任務執行時間長是因為cpu的消耗則應使用同步操作(此時非同步作業不會改善任何問題) * 原理是什嗎? * 在 Web 服務器上,.NET Framework 維護一個用於服務 ASP.NET 請求的線程池(以下把 .NET Framework 維護的用於服務 ASP.NET 請求的線程池稱作為“特定線程池”) * 同步操作時,如果特定線程池利用滿了,則不會再提供服務 * 非同步作業時: * 1、一個請求過來,特定線程池出一個線程處理此請求 * 2、啟動一個非特定線程池中的另一個線程處理非同步作業,此時處理此請求的線程就會空出來,不會被阻塞,它可以繼續處理其它請求 * 3、非同步作業執行完畢後,從特定線程池中隨便找一個空閑線程返回請求結果 */using System;using System.Collections.Generic;using System.Linq;using System.Net;using System.Net.Http;using System.Threading.Tasks;using System.Web.Http;namespace MVC40.Controllers{ public class AsyncController : ApiController { public async Task<string> Get() { return await GetData(); } [NonAction] public async Task<string> GetData() { await Task.Delay(10 * 1000); return "長時間的任務執行完畢"; } }}
OK
[源碼下載]