iT邦幫忙

0

[C#][ASP.NET] 如何在 .NET Framework 4.0 加入 Web Api

這篇是寫給想要在舊專案偷渡 Web Api 的朋友看的。 (́◕◞౪◟◕‵)*

之前也寫過類似的文章 [C#][ASP.NET] Web API 開發心得 (1) - WebForm 搭配 Web API
不過很遺憾 .NET Framework 4.0 無法使用 Web Api 2,因此才會有這篇的出現,這篇會介紹如何在 4.0 的環境加入初代 Web Api,雖然功能沒有之後的版本強大,不過總比什麼都沒有好 ~~~

1. 安裝的套件 (Nuget)

  • Microsoft.AspNet.WebApi - 4.0.30506

要注意版本,太新不能安裝。

2. 開啟 Global.asax 在 Application_Start 加入路由設定

public partial class Global : HttpApplication
{
    void Application_Start(object sender, EventArgs e)
    {
        var config = GlobalConfiguration.Configuration;

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    } 
}

3. 因為 api 預設會回傳 xml 如果想改成 json 可以加入以下程式

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

//移除 XML Formatter
var appXmlType =config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefaul(t => t.MediaType == "application/xml");
config.Formatters.XmlFormatter.SupportedMediaTypes.Remov(appXmlType);

//JSON 縮排
config.Formatters.JsonFormatter.SerializerSettings.Formatting =Newtonsoft.Json.Formatting.Indented;

4. 新增 TestController.cs 檔案必需放在 App_Code 資料夾內

public class TestController : ApiController
{
    public object Get() 
    {
        return new
        {
            s = "Hi~Hi~"
        };
    }
}

結果

/DotNetFramework4/api/Test

https://ithelp.ithome.com.tw/upload/images/20191214/20106865k3DwoT61z7.jpg

不過這樣有個缺點,因為比起 MVC 的路由少了一層 Action,因此必需透過 http method 決定要執行的方法,使用起來不太方便,所以開始研究有沒有其他設定方式。

翻了微軟文件,雖然不能像 Web Api 2 一樣完全自訂路由,但有幾個 Attribute 加入後應該還是不錯的。

1. 調整路由設定加入 {action}

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

2. 在程式內加入 [HttpGet] 和 [ActionName("xxx")] 這兩個 Attribute 控制路由

更多用法可以參考微軟文件: ASP.NET Web API 中的路由

public class TestController : ApiController
{
    [HttpGet]
    [ActionName("getList")]
    public object GetList() 
    {
        return new List<string>
        {
            "123",
            "456"
        };
    }

    [HttpGet]
    [ActionName("getItem")]
    public object GetItem()
    {
        return "abc";
    }
}

結果

/DotNetFramework4/api/Test/getList

https://ithelp.ithome.com.tw/upload/images/20191214/201068655dtJ53ef9X.jpg

/DotNetFramework4/api/Test/getItem

https://ithelp.ithome.com.tw/upload/images/20191214/20106865DhMK5XTTPu.jpg


因為 Web Api 是無狀態的,所以程式中如果有使用到 Session 會出錯。

[HttpGet]
[ActionName("getSession")]
public object GetSession()
{
    var httpContext = HttpContext.Current;

    httpContext.Session["test"] = "hellow";

    return httpContext.Session["test"];
}

找不到 Session 執行個體。

https://ithelp.ithome.com.tw/upload/images/20191214/20106865etgYhzbkhq.jpg

開啟 Global.asax 在 Application_PostAuthorizeRequest 加入以下程式

判斷網址開頭如果是 api,設定 SessionStateBehavior.Required,這樣就可以在 Controller 內使用 Session。

private bool IsWebApiRequest()
{
    return HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath.StartsWith("~/api");
}

void Application_PostAuthorizeRequest()
{
    if (IsWebApiRequest())
    {
        HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
    }
}

結果

https://ithelp.ithome.com.tw/upload/images/20191214/201068651EjmFLtYGP.jpg


補充

Global.asax 有兩種寫法。

第一種

程式碼和標籤寫在一起。

Global.asax

<%@ Application Language="C#" %>

<script runat="server">
    void Application_Start(object sender, EventArgs e)
    {
        ...
    }
</script>

第二種

程式碼和標籤分開檔案,又稱為 Code Behind。

Global.asax

<%@ Application Language="C#" Inherits="AppsCore.Global" %>

Global.asax.cs 檔案放在 App_Code

namespace AppsCore
{
    public partial class Global : HttpApplication
    {
        void Application_Start(object sender, EventArgs e)
        {
            ...
        }
    }
}

如何在第一種寫法,引用 System.Web.Http?

可以使用 Import 標籤,如下:

<%@ Import Namespace="System.Web.Http" %>

完整程式:

<%@ Application Language="C#" %>

<%@ Import Namespace="System.Web.Http" %>

<script runat="server"> 
    void Application_Start(object sender, EventArgs e)
    {
        var config = GlobalConfiguration.Configuration;
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = System.Web.Http.RouteParameter.Optional }
        );
    }
</script>

結語

這篇就到這裡,感謝大家觀看,祝大家偷渡愉快。 \(★´▽`)人(´▽`★)/

參考文章

[Web API]在VS2010 .Net Framework 4.0 環境下使用Web API 1
HttpConfiguration missing assembly
ASP.NET Web API 中的路由
Accessing Session Using ASP.NET Web API


尚未有邦友留言

立即登入留言