Nancy(1)-快速建立簡單Http Server

Nancy一個輕量級Web Framework。

最近我需要模擬http response,我需要快速建立一個http server,

透過谷哥發現Nancy符合我要的快速、輕量、簡單原則,

同時一些我需要的基本功能,如診斷儀表板、驗證、SSL..等一應俱全,

也支援DELETE, GET, HEAD, OPTIONS, POST, PUT and PATCH動詞,

不多說,馬上示範如何快速建立一個http Server。

 

先透過NG安裝

Install-Package Nancy.Hosting.Self

實務上我寫一隻Windows Service,但這裡我使用Console application示範。

class Program
    {
        string URL = "http://localhost";
        int PORT =9487;
        NancyHost _NancyHost;

        public Program()
        {
            var uri = new Uri($"{URL}:{PORT}/");
            //var hostConfiguration = new HostConfiguration();
            _NancyHost = new NancyHost(uri);
        }

        private void Start()
        {
            _NancyHost.Start();
            Console.WriteLine($"Started listennig.... {URL}:{PORT}");
            Console.ReadKey();
            _NancyHost.Stop();
        }

        static void Main(string[] args)
        {
            var p = new Program();
            p.Start();
        }
    }

執行後你會看到Nancy啟動錯誤,這是因為權限問題,你可以透過CreateAutomatically自動保留URL,

或是使用Administrator啟動,另外就是手動建立註冊URL保留區。

netsh http add urlacl url="http://+:9487/" user="Everyone"

查看URL保留區: netsh http show urlacl

再次執行即可正常啟動Nancy

開啟browser輸入http://localhost:9487,即可看到http server返回404

撰寫Request

所有Request都必須繼承NancyModule,下面我建立post和Get兩個動詞。

public class TestModule : NancyModule
    {
        public TestModule()
        {
            Get["/"] = _ => "Hello Nancy from Get request";

            Post["/"] = _ => "Hello Nancy from Post request";
        }
    }

Html、Htm、SSHtml測試

View:

Get["/Home"] = Post["/Home"] = parameters =>
            {
                var usersmodel = new List<User>();
                usersmodel.Add(new User { Name = "rico" });
                usersmodel.Add(new User { Name = "sherry" });

                this.ViewBag.data = "From Nancy";

                return View["Index.sshtml", usersmodel];
            };

參數測試

Get["/User/{Name}"] = p =>
            {
                if (p.Name =="rico" )                
                    return $"Admini user #{p.Name}!";
                
                else                
                    return $"Normal user #{p.Name}!";                
            };

Request Body傳送JSON格式測試

Post["/"] = _ =>
            {
                var Name = this.Request.Body;             
                var length = this.Request.Body.Length;
                var data = new byte[length];
                Name.Read(data, 0, (int)length);
                var body = System.Text.Encoding.Default.GetString(data);
                var requestPOCO = JsonConvert.DeserializeObject<User>(body);//Install-Package Nancy.Serialization.JsonNet
                return $"Name:{requestPOCO.Name}#Age:{requestPOCO.Age}#IsAdmin:{requestPOCO.IsAdmin}";
               
            };

Model Binding測試

Post["/"] = _ =>
              {
                  var requestPOCO = this.Bind<User>();
                  return $"Name:{requestPOCO.Name}";
              };

自訂header的response測試

Post["/Rico"] = _ =>
            {
                string jsonString = "{ Name: \"Rico\", Age: \"35\" }";
                byte[] jsonBytes = Encoding.UTF8.GetBytes(jsonString);

                return new Response()
                {
                    StatusCode = HttpStatusCode.OK,
                    ContentType = "application/json",
                    ReasonPhrase = "Rico Customize",
                    Headers = new Dictionary<string, string>()
                        {
                        { "Content-Type", "application/json" },
                        { "X-Custom-Header", "I am Rico" }
                        },
                    Contents = c => c.Write(jsonBytes, 0, jsonBytes.Length)
                };//Response.AsJson or  Response.AsXml

            };

忍不住說~~~Nancy好威

 

參考

http://nancyfx.org/