實現 WebApi 自托管服務宿主於 WinForms 及其交互


在 Windows 平台 Web 服務一般托管於 IIS. 在開發中, 會遇到 WinForms 或 WPF 服務端程序需要提供對外 API 作為服務. 在本文詳細介紹 WebApi 自托管於 WinForms 中, WPF 或 Console 程序實現類似.

0. 完整示例演示

示例演示

1. 新建解決方案以及 WinForms 工程

1.1. 新建解決方案及工程

如下圖所示:

解決方案結構

  • 建立空白解決方案及 Winforms 工程,
  • 新建 Controllers 文件夾用於存放 WebApi 代碼,
  • 新建 Services 文件夾用於存放服務代碼.

1.2. 拖拽控件

繪制必要控件, 布局如下:

窗體布局

備注: 繪制一個 NumericUpDown 和兩個 Button 控件.

1.3. 引用相關開發包:

  • Microsoft.AspNet.WebApi.Client
  • Microsoft.AspNet.WebApi.Core
  • Microsoft.AspNet.WebApi.SelfHost

2. 開發 HTTP 服務類

/// <summary>
/// HTTP service.
/// </summary>
public class HttpService : IDisposable
{
    /// <summary>
    /// HTTP server's listening port.
    /// </summary>
    public int Port { get; set; }

    /// <summary>
    /// HTTP self hosting.
    /// </summary>
    private readonly HttpSelfHostServer _server;

    /// <summary>
    /// HTTP server.
    /// </summary>
    /// <param name="port">Listening port.</param>
    public HttpService(int port)
    {
        this.Port = port;

        var config = new HttpSelfHostConfiguration($"http://0.0.0.0:{this.Port}");

        config.MapHttpAttributeRoutes();
        config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{action}");

        _server = new HttpSelfHostServer(config);
    }

    #region HTTP Service

    /// <summary>
    /// start HTTP server.
    /// </summary>
    public Task StartHttpServer()
    {
        return _server.OpenAsync();
    }

    /// <summary>
    /// Close HTTP server.
    /// </summary>
    public Task CloseHttpServer()
    {
        return _server.CloseAsync();
    }

    #endregion

    /// <summary>
    /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
    /// </summary>
    public void Dispose()
    {
        _server?.Dispose();
    }
}

WebApi 自托管服務主要由 HttpSelfHostServer 實現, 其 OpenAsync 開啟 HTTP 監聽, CloseAsync 關閉 HTTP 監聽.

config.MapHttpAttributeRoutes();

可以在 Controller 中使用路由特性.

3. 調用 HTTP 服務

在 MainForm 窗體程序中引用 HTTP 服務:


public class MainForm:Form
{
    /// <summary>
    /// Http service.
    /// </summary>
    private HttpService _http;
}

3.1. 編寫開啟 HTTP 服務代碼

/// <summary>
/// start the http server.
/// </summary>
private async void StartButton_Click(object sender, EventArgs e)
{
    /**
     * start.
     */
    try
    {
        var port = Convert.ToInt32(this.PortNum.Value);

        /**
         * initialize http service.
         */
        _http = new HttpService(port);

        await _http.StartHttpServer();
    }
    catch (Exception exception)
    {
        MessageBox.Show($"{exception.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

3.2. 編寫關閉 HTTP 服務代碼

/// <summary>
/// close the http server.
/// </summary>
private async void CloseButton_Click(object sender, EventArgs e)
{
    /**
     * close.
     */
    try
    {
        await _http.CloseHttpServer();
        _http.Dispose();
    }
    catch (Exception exception)
    {
        MessageBox.Show($"{exception.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

4. 開發控制器

/// <summary>
/// Home controller.
/// </summary>
[RoutePrefix("api/home")]
public class HomeController : ApiController
{
    /// <summary>
    /// Print the greetings
    /// </summary>
    /// <param name="name">visitor</param>
    /// <returns>greetings</returns>
    [Route("echo")]
    [HttpGet]
    public IHttpActionResult Echo(string name)
    {
        return Json(new {Name = name, Message = $"Hello, {name}"});
    }
}

5. 合在一起

解決方案完整結構

下載完整示例代碼 (GitHub)

6. 注意事項

程序需要擁有 管理員權限 才能開啟 HTTP 監聽, 在調試時, 若 Visual Studio 為擁有管理員權限, 則無法正常運行. 同樣地, 在程序編譯生成之后運行時亦需要權限.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM