FastHttpApi相对于asp.net mvc来说有着更轻量和性能上的优势,性能上面就不在这里介绍了(具体可查看 https://github.com/IKende/FastHttpApi)。在这里主要讲解一下如何使用FastHttpApi进行网站或WebApi开发,在使用FastHttpApi之前必须了解它具备那些功能,它除了提供webapi服务的编写外还提供了静态资源的支持,简单来说FastHttpApi除了能实现基于HTTP的服务交互外还能实现应用网站;虽然不提供视MVC那样的视图处理功能,但可以通过现有比较成熟的前后端分离技术来实现应用网站的编写。以下是简单地描述一下FastHttpApi的功能:

  1. 支持以函数的方式来制定HTTP请求逻辑
  2. 支持使用者处理异步响应
  3. 支持Filter功能,以便更好地控制请求方法的处理
  4. 支持自定义Http Body解释器,方便制定基于json,xml,protobuf,msgpack等数据格式的传输
  5. 支持QueryString参数和Cookies
  6. 支持外置或内嵌到DLL的静态资源输出(默认对html,js,css资源进行GZIP处理)
  7. 支持SSL

在后续版升级主要功能:同一服务端口的控制器逻辑会同时兼容http和websocket两种协议请求

通过以上功能完全可以用来构建高效全安的应用网站。以下通过一些例子详细讲述如何使用FastHttpApi。

定义HTTP请求的方法

在FastHttpApi定义HTTP请求的方法和asp.net webapi差不多,都是通过定义一个控制器然后定义相关请求方法即可,当然使用起来会简单一些。以下以Northwind的数据作为基础制定了一个简单的数据访问控制器

  1. [FastHttpApi.Controller]
  2. public class Controller
  3. {
  4. public Controller()
  5. {
  6. mEmployees = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Employee>>(Datas.Employees);
  7. mCustomers = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Customer>>(Datas.Customers);
  8. mOrders = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Order>>(Datas.Orders);
  9. }
  10. private List<Employee> mEmployees;
  11. private List<Customer> mCustomers;
  12. private List<Order> mOrders;
  13. public Employee GetEmployee(int id)
  14. {
  15. Employee result = mEmployees.Find(e => e.EmployeeID == id);
  16. if (result == null)
  17. result = new Employee();
  18. return result;
  19. }
  20. public bool EditEmployee(int id, [BodyParameter]Employee emp, FastHttpApi.HttpResponse response)
  21. {
  22. Employee record = mEmployees.Find(e => e.EmployeeID == id);
  23. if (record != null)
  24. {
  25. record.City = emp.City;
  26. record.Address = emp.Address;
  27. record.Title = emp.Title;
  28. record.HomePhone = emp.HomePhone;
  29. return true;
  30. }
  31. return false;
  32. }
  33. public object ListEmployees()
  34. {
  35. return mEmployees;
  36. }
  37. public object GetEmployeesName()
  38. {
  39. return from e in mEmployees select new { ID = e.EmployeeID, Name = e.FirstName + " " + e.LastName };
  40. }
  41. public object GetCustomersName()
  42. {
  43. return from c in mCustomers select new { ID = c.CustomerID, Name = c.CompanyName };
  44. }
  45. public object ListOrders(int employeeid, string customerid)
  46. {
  47. return mOrders.Where(o =>
  48. (employeeid == || o.EmployeeID == employeeid)
  49. &&
  50. (string.IsNullOrEmpty(customerid) || o.CustomerID == customerid));
  51. }
  52. }

相对于asp.net webapi来说,组件中会把所有控制器Public方法注册为URL,方法是不区分GET或POST,如果有需要可以通过HttpRequest中获取;参数根据自己需要来定义,参数有两种来源一种是通过QueryString获取而另一种则通过HttpBody获取;对于HttpResponse和HttpRequest则看情况需要,如果有需要直接在方法中定义相关类型参数即可获取。当控制器编写完成后,需要给类写上[Controller]标签告诉组件这是一个api控制器接收HTTP请求。

异步应答处理

对于HTTP来说,一个请求就必须要应答,因为这是HTTP协议规范;在实际业务中往往方法处理完成就进行应答,但有些情况下需要异步应答;当一个业务需要处理大量IO的业务时那就会把线程处于等待状态,为了更好地处理这种情况组件提供了异步应答处理;通过异步应答可以在大量IO处理异步回调后再进行应答处理。

  1. public void asyncHello(string name, HttpResponse response)
  2. {
  3. response.Async();
  4. Task.Run(() =>
  5. {
  6. Console.WriteLine("sleep ...");
  7. System.Threading.Thread.Sleep();
  8. response.Result(string.Format("[{0}] hello {1}", DateTime.Now, name));
  9. });
  10. }

通过HttpResponse.Async方法告诉组件是异步应答,组件在这个方法执行完成后不会进行HTTP响应。实际响应是使用者需要显式地调用HttpResponse.Result方法来进行应答。

filter的应用

相信写过asp.net mvc的朋友对filter并不陌生,它的主要工作就是对请求方法进行拦截控制。FastHttpApi支持使用都定义任意功能的Filter,用来记录日志、控制权限等等。编写好的控制器可以标记在Controller上,生效于所有相关主求方法;也可以针对个别方法标记上。组件除了提供Filter外还提供了SkipFilter,它的主要作用是移走某些不需要的Filter拦截器。

  1. public class GlobalFilter : FilterAttribute
  2. {
  3. public override void Execute(ActionContext context)
  4. {
  5. Console.WriteLine(DateTime.Now + " globalFilter execting...");
  6. context.Execute();
  7. Console.WriteLine(DateTime.Now + " globalFilter executed");
  8. }
  9. }

以上是标记一个全局的Filter,用于记录方法执行前和执行后的时候,context.Execute()是告诉组件往下执行;如果判断权限,则在这里可以依据HttpRequest的信息情况来决定是否执行context.Execute(),这样就起到了权限控制的作用。当希望某个方法不经过这个Filter的情况下可以这样做:

  1. [SkipFilter(typeof(GlobalFilter))]
  2. [CustomFilter]
  3. public string Hello(string name)
  4. {
  5. return DateTime.Now + " hello " + name;
  6. }

HTTP消息体解释器

组件通过IBodySerializer接口来规范HTTP消息体的解释和一些错误状态返回的数据

  1. public interface IBodySerializer
  2. {
  3.  
  4. int Serialize(PipeStream stream, object data);
  5.  
  6. bool TryDeserialize(PipeStream stream, int length, Type type, out object data);
  7.  
  8. object GetNotFoundData(HttpResponse response);
  9.  
  10. object GetInnerError(Exception e, HttpResponse response, bool outputStackTrace);
  11.  
  12. object GetNotSupport(HttpResponse response);
  13.  
  14. string ContentType { get; set; }
  15. }

接口提供的功能比较少,主要包括消息的序列化、反序列化和一些HTTP状态的处理,随便着功能的完善后期这接口可能会添加更多的方法。以下是针对Json实现的一个解释器,毕竟在WEB通讯中json是最常用的(如果是网内服务交互为了提高效率可以实现protobuf,msgpack等二进制序列化)。

  1. public virtual int Serialize(PipeStream stream, object data)
  2. {
  3. int length = stream.CacheLength;
  4. string value = Newtonsoft.Json.JsonConvert.SerializeObject(data);
  5. stream.Write(value);
  6. return stream.CacheLength - length;
  7. }
  8.  
  9. public virtual bool TryDeserialize(PipeStream stream, int length, Type type, out object data)
  10. {
  11. data = null;
  12. if (stream.Length >= length)
  13. {
  14. string value = stream.ReadString(length);
  15. if (type != null)
  16. {
  17. data = Newtonsoft.Json.JsonConvert.DeserializeObject(value,type);
  18. }
  19. else
  20. {
  21. data = Newtonsoft.Json.JsonConvert.DeserializeObject(value);
  22. }
  23. return true;
  24. }
  25. return false;
  26. }

可能通过以下方式'mApiServer.ServerConfig.BodySerializer = new JsonBodySerializer();'来设置相应HTTP服务的消息转换器。

Cookies处理

FastHttpApi和asp.net mvc处理的方式差不多,通过HttpResponse进行Cookie的写入,由HttpRequest来获取Cookie值。

  1. public bool setCookie(string name, string value, HttpResponse response)
  2. {
  3. response.SetCookie(name, value);
  4. return true;
  5. }
  6.  
  7. public void getCookie(string name, HttpRequest request, HttpResponse response)
  8. {
  9. string value = request.Cookies[name];
  10. response.Result(value);
  11. }

网页资源处理

组件处理的网页资源需要存放在当前项目的views目录下,views目录可以说是网页资源的根目录。网页资源有两种打包方式,一种是编译复制到发布目录下,而另一种则是嵌入到编译资源中;建议选择嵌入资源的发布方式,这样最终发布的时候就只需要复制一个DLL即可,不过这种方式发布需要修改网页资源都需要重新发布。对于编译复制发布的好处是可以直接修改,组件会检则修改情况重新刷新资源缓存。 组件处理网页资源有两种方式,对于image的资源组件是在头上标识为客户端缓存,在没过期的情况客户端不会二次请求图片资源。那对于HTML,CSS,JS这些文件组件会加个缓存标签,当文件发生变化会重新响应给客户端,否则响应304给客户端。

开发阶段调试简化

由于网页资源需要编译才会被重新复制或嵌入的到程序中,这样每修改一次都要编译查看结果那是很麻烦的事情,也浪费大量工作时间。所以在启动服务的时候执行一下HttpApiServer.Debug方法,通过这个方法可以把网页资源目录指向项目中网页资源的目录,这样修改网页也不需要重新编译即可查看。 HttpApiServer.Debug只有在Debug模式下才能生效。 (提示FastHttpApi的url不区分大小写)

以下是NorthWind数据订单查询的页面代码

  1. <script>
  2. $(document).ready(function () {
  3. $.get("/GetEmployeesName", function (items) {
  4. items.forEach(function (v, i) {
  5. $('#lstEmployees').append(' <option value="' + v.ID + '">' + v.Name + '</option>')
  6. });
  7. });
  8. $.get("/GetCustomersName", function (items) {
  9. items.forEach(function (v, i) {
  10. $('#lstCustomers').append(' <option value="' + v.ID + '">' + v.Name + '</option>')
  11. });
  12. });
  13. search();
  14. });
  15. function search() {
  16. $.get('/listorders?employeeid=' + $('#lstEmployees').val() + "&customerid=" + $('#lstCustomers').val(), function (items) {
  17. $("#lstbody").empty();
  18. items.forEach(function (v, i) {
  19. $("#lstbody").append('<tr><td>' + i + '</td><td>' + v.OrderID + '</td><td>' + v.ShipName + '</td><td>' + v.ShipAddress + '</td><td>' + v.ShipCity + '</td><td>' + v.OrderDate + '</td></tr>')
  20. });
  21. });
  22. }
  23. </script>

运行服务

FastHttpApi启动Http服务非常简单,并不需要做太多的配置即可运行

  1. private static HttpApiServer mApiServer;
  2. static void Main(string[] args)
  3. {
  4. mApiServer = new HttpApiServer();
  5. mApiServer.ServerConfig.BodySerializer = new JsonBodySerializer();
  6. mApiServer.Register(typeof(Program).Assembly);
  7. //config.SSL = true;
  8. //mApiServer.ServerConfig.CertificateFile = @"c:\ssltest.pfx";
  9. //mApiServer.ServerConfig.CertificatePassword = "123456";
  10. mApiServer.Debug();
  11. mApiServer.Open();
  12. Console.Write(mApiServer.BaseServer);
  13. Console.Read();
  14. }

如果希望修改一些基础配置信息,如服务IP和端等可以通过HttpApiServer.ServerConfig来修改;也可以通过HttpConfig.json来配置相应信息.

(具体代码查看:https://github.com/IKende/FastHttpApi/tree/master/samples

dotnet core使用开源组件FastHttpApi进行web应用开发的更多相关文章

  1. dotnet core使用开源组件FastHttpApi进行web应用开发(转)

      FastHttpApi相对于asp.net mvc来说有着更轻量和性能上的优势,性能上面就不在这里介绍了(具体可查看 https://github.com/IKende/FastHttpApi). ...

  2. 二十三、【开源】EFW框架Web前端开发之常用组件(FusionCharts图表、ReportAll报表等)

    回<[开源]EFW框架系列文章索引>        EFW框架源代码下载V1.2:http://pan.baidu.com/s/1hcnuA EFW框架实例源代码下载:http://pan ...

  3. dotnet core 实践——日志组件Serilog

     前几天把基于quartz.net的部分项目代码移植到了dotnet core ,但是没增加日志功能,原因是没找到合适的组件. 今天终于找到了Serilog: https://github.com/s ...

  4. dotnet core各rpc组件的性能测试

    一般rpc通讯组件都具有高性特性,因为大部分rpc都是基于二进制和连接复用的特点,相对于HTTP(2.0以下的版本)来说有着很大的性能优势,非常适合服务间通讯交互.本文针对了dotnet core平台 ...

  5. [dotnet core]使用Peach简化Socket网络通讯协议开发

    Peach是基于DotNetty的Socket网络通讯帮助类库,可以帮助开发者简化使用DotNetty,关于DotNetty可参考我之前的这篇文章. Peach内置实现了一个基于文本协议的Comman ...

  6. NET Core & VS Code 之路(2) Web API

    NET Core & VS Code 之路(2) Web API 开发Core项目的条件 Visual Studio 2015 Update 3 .NET Core 1.0.0 - VS 20 ...

  7. dotnet core高吞吐Http api服务组件FastHttpApi

    简介 是dotNet core下基于Beetlex实现的一个高度精简化和高吞吐的HTTP API服务开源组件,它并没有完全实现HTTP SERVER的所有功能,而是只实现了在APP和WEB中提供数据服 ...

  8. .NET Core第三方开源Web框架YOYOFx

    YOYOFx框架 YOYOFx是一个轻量级用于构建基于 HTTP 的 Web 服务,基于 .NET 和 Mono 平台. 本着学习的态度,造了这个轮子,也是为了更好的了解各个框架的原理和有点,还希望可 ...

  9. Core第三方开源Web框架

    NET Core第三方开源Web框架YOYOFx   YOYOFx框架 YOYOFx是一个轻量级用于构建基于 HTTP 的 Web 服务,基于 .NET 和 Mono 平台. 本着学习的态度,造了这个 ...

随机推荐

  1. BZOJ.4144.[AMPPZ2014]Petrol(Kruskal重构树)

    BZOJ 看别人代码的时候发现哪一步都很眼熟,突然想起来,就在四个月前我好像看过还给别人讲过?mmp=v= 果然不写写就是容易忘.写了好歹忘了的时候还能复习呢(虽然和看别人的好像也没多少差别?). 首 ...

  2. dnmp(docker的lnmp)安装WordPress之后图片上传问题 问题:图片上传大小问题解决和 报错413 Request Entity Too Large

    首先是提示超过图片尺寸和大小, 最后发现都是图片大小的问题, 需要修改php的最大上传size 修改之后查看php配置  已经生效  但是还是报错, 提示返回不是合法的json,  查看控制台, 报错 ...

  3. 树莓派虚拟环境手动安装HA

    树莓派手动安装 https://www.home-assistant.io/docs/installation/raspberry-pi/ sudo apt-get update sudo apt-g ...

  4. TypeScript专题-Static和使用技巧

    class People { static _name: string; print() { //alert(this.name);// 编译不通过,doex not exist on type Pe ...

  5. canvas生成海报

    虽然之前也做过类似的生成海报的项目,但是这个项目我又网上查找了一下,发现一个插件挺好用的  html2canvas.js http://html2canvas.hertzen.com/这里可以下载这个 ...

  6. Chrome_高亮显示当前改变的区域

  7. Django model对象接口

    Django model查询 # 直接获取表对应字段的值,列表嵌元组形式返回 Entry.objects.values_list('id', 'headline') #<QuerySet [(1 ...

  8. 【原创】XAF CriteriaOperator 使用方式汇总

    1.CriteriaPropertyEditor [EditorAlias(EditorAliases.CriteriaPropertyEditor)] [CriteriaOptions(" ...

  9. 快速搭建react项目骨架(按需加载、redux、axios、项目级目录等等)

    一.前言 最近整理了一下项目骨架,顺便自定义了一个脚手架,方便日后使用.我会从头开始,步骤一步步写明白,如果还有不清楚的可以评论区留言.先大致介绍一下这个骨架,我们采用 create-react-ap ...

  10. ArcGIS Runtime For Android 100.3天地图不加载问题

    ArcGIS Runtime 100.3 不加载天地图问题 参考这篇帖子:https://community.esri.com/thread/220496-1003-webtiledlayer-can ...