WebAPi返回类型到底应该是什么才合适,这是个问题?

前言

有些问题只有真正遇到或者用到并且多加思考才会想到,平常若作为自学的心态去学习则不会考虑太多,我慢慢明白对于那些有太多要学的东西或者说的更加明确而且具体一点的话,如果对于你现在不是迫切要学或者需要掌握的技能,那就暂且放在一边吧,比如现在比较火的angular和react,我之前也花时间去学了,但是公司压根不用或者有专门的前端你学多了貌似没什么很大的实际用途,其实仅仅做一点基本的了解即可,至少别人问起也知道一二,不要看到别人学什么或者火了什么就盲目跟风,还是根据自身实际情况来学习才是王道。这不刚说到根据自身来学习,脑袋妄想着正在做的项目,突然冒出一个想法,为什么那不可以,为什么它又存在呢?这篇文章就出来了。

话题介绍

我们知道在WebAPi中对于响应结果我们都是这样用的:

        public HttpResponseMessage GetResult<T>(T t)
        {
            return Request.CreateResponse<T>(HttpStatusCode.OK, t);
        }

在项目中前端为了和其他统一,封装了一套响应的结果和状态码,要求直接返回对象,于是将上述修改成比如如下:

    public Result<List<Person>> GetResult()
    {
       var result = new Result<List<Person>>();
       return result;
    }

    public class Result<T> : BaseResult
    {
        public T Data;
    }

    public class BaseResult
    {
        public string Message;
        public int Status;
        public ErrorCode ErrorCode;
    }

    public enum ErrorCode
    {
    ......
    }

统观以上两种方法,一种是WebAPi内置响应的结果,另外一种则是直接返回自定义响应结果。

于是乎,我开始思索这两种方法虽然都能得到我们想要的结果,但是有什么区别没有呢?说的更加明确一点的是,二者在数据响应上有没有性能上的差异呢?

WebAPi响应结果和自定义响应结果二者性能差异

以上则是需要返回对象来进行处理,而有些我们则不需要返回任何对象来进行处理例如直接返回void,而在WebAPi中对应需要返回 IHttpActionResult 例如自定义返回则是如下:

   public void GetFirst()
   {.....}

在WebAPi中则是进行如下返回:

   public IHttpActionResult GetSecond()
   {
     return OK();
   }

下面我们在控制台中分别来测试这二者在WebHost以及在SelfHost上的差异,我们如何获取其差异呢?我们通过对void方法和http方法在控制台中发出1000个请求来获取其总共花费时间来进行比较。

SelfHost

       [HttpGet]
        public void GetFirst()
        {
            StringBuilder stringbuilder = new StringBuilder();
            for (int i = 0; i < 20; i++)
            {
                stringbuilder.Append("something");
            }
        }

        [HttpGet]
        public IHttpActionResult GetSecond()
        {
            StringBuilder stringbuilder = new StringBuilder();
            for (int i = 0; i < 20; i++)
            {
                stringbuilder.Append("something");
            }
            return Ok();
        }

在控制台中方法如下:

        private const string voidUrl = "http://localhost:8080/api/home/GetFirst";
        private const string httpUrl = "http://localhost:8080/api/home/GetSecond";
        private static List<TimeSpan> voidTimes = new List<TimeSpan>();
        private static List<TimeSpan> httpTimes = new List<TimeSpan>();
        static void Main(string[] args)
        {
            Console.WriteLine("Start Test....");
            for (int i = 0; i < 1000; i++)
            {
                voidTimes.Add(getResponse(voidUrl));
                Thread.Sleep(10);
                Console.WriteLine("void Test " + i);
            }
            Console.WriteLine("Finished Void Test");
            for (int i = 0; i < 1000; i++)
            {
                httpTimes.Add(getResponse(httpUrl));
                Thread.Sleep(10);
                Console.WriteLine("http Test " + i);
            }
            Console.WriteLine("Finished Http Test");
            var voidTotalTime = voidTimes.Sum(t => t.Milliseconds);
            Console.WriteLine("void方法发出1000个请求总共需要时间:" + voidTotalTime);
            Console.WriteLine("void方法平均每一个请求需要时间:" + voidTotalTime / 1000.00 + "秒");

            var httpTotalTime = httpTimes.Sum(t => t.Milliseconds);
            Console.WriteLine("http方法发出1000个请求总共需要时间: " + httpTotalTime);
            Console.WriteLine("http方法平均每一个请求需要时间: " + httpTotalTime / 1000.00 + "秒");

            Console.Read();
        }

        static TimeSpan getResponse(string url)
        {
            var stopWatch = new Stopwatch();
            stopWatch.Start();
            var httpClient = new HttpClient();
            httpClient.BaseAddress = new Uri(url);
            var task = httpClient.GetAsync(httpClient.BaseAddress).Result;
            var result = task.Content.ReadAsAsync(typeof(object));
            var timeSpan = stopWatch.Elapsed;
            stopWatch.Stop();
            return timeSpan;
        }

下面我们来直观演示整个过程:

从上看出似乎由http方法节约一点时间,我们将上述中的方法循环次数,进行如下修改:

            for (int i = 0; i < 200000; i++)
            {
                stringbuilder.Append("something");
            }

这时候我们再来看看结果:

当有二十万条数据时此时时间又多节约一点点。接下来我们再来测试WebHost。

WebHost

在WebHost中我们利用特性来管理请求方法:

        [HttpGet]
        [Route("test/void")]
        public void GetFirst()
        {
            StringBuilder stringbuilder = new StringBuilder();
            for (int i = 0; i < 20; i++)
            {
                stringbuilder.Append("something");
            }
        }

        [HttpGet]
        [Route("test/IHttpActionResult")]
        public IHttpActionResult GetSecond()
        {
            StringBuilder stringbuilder = new StringBuilder();
            for (int i = 0; i < 20; i++)
            {
                stringbuilder.Append("something");
            }
            return Ok();
        }

此时将控制台请求地址进行对应修改即可:

 private const string voidUrl = "http://localhost:2531/test/void";
 private const string httpUrl = "http://localhost:2531/test/IHttpActionResult";

此时演示结果如下:

此时快了接近一秒。此时我们将数据增加到同样20万时再看看:

此时还是快了1秒。到了这里是不是就算结束了呢,我们再来看看

当我们请求void方法时返回的状态码为如下:

此时利用http来进行响应则是如下:

其返回状态也不同,我们则需要有对应的处理方式。

总结

在演示void方法和http方法时有时也会出现http方法时间比void方法慢的原因,不知是何缘故,理论上来说用HttpResponseMessage来作为响应结果会快一点,因为HttpResponseMessage内置对于一些异常都做了处理并返回对应的状态码而void方法则未做任何处理。但是从另外一个角度看,若我们自定义一套返回的状态码来进行处理也并非不可,个人觉得利用WebAPi内置的HttpResponseMessage响应机制来进行结果响应最佳,期待各位的批评和答案,同时不知上述测试是否合理。当时想到这个问题时也查了相关资料,还真有做过类似测试的,于是借用了一下。

参考资料:http://stackoverflow.com/questions/22689888/webapi-2-is-a-void-response-faster-then-ihttpactionresult

时间: 2024-08-24 16:59:53

WebAPi返回类型到底应该是什么才合适,这是个问题?的相关文章

WebApi返回类型设置为json的三种方法

web api写api接口时默认返回的是把你的对象序列化后以XML形式返回,那么怎样才能让其返回为json呢,下面就介绍两种方法: 方法一:(改配置法) 找到Global.asax文件,在Application_Start()方法中添加一句: GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear(); 修改后: protected void Application_Start() {

webapi返回文件流

逻辑说明 webapi返回类型为IHttpActionResult接口,内部方法返回HttpResponseMessage. public interface IHttpActionResult { Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken); } 参照JsonResult<T>,自定义返回文件流. 主要为:设置文件响应内容流,文件内容类型,文件名. HttpResponse

webapi的返回类型,webapi返回图片

1.0 首先是返回常用的系统类型,当然这些返回方式不常用到.如:int,string,list,array等.这些类型直接返回即可. 1 public List<string> Get() 2 { 3 List<string> list = new List<string>() { "11","22","33"}; 4 return list; 5 } 1.1 用不同的浏览器测试发现,返回的类型竟然是不一样的.

【转载】C#.NET WebApi返回各种类型(图片/json数据/字符串),.net图片转二进制流或byte

C#.NET WebApi返回各种类型(图片/json数据/字符串),.net图片转二进制流或byte 转载:http://www.itdos.com/Mvc/20150302/0741255.html using System.IO; /// <summary> /// WebApi返回图片 /// </summary> public HttpResponseMessage GetQrCode() { var imgPath = @"D:\ITdosCom\Images

WebAPi学习笔记之 Api和返回类型(Action Results in Web API 2)

这篇文章主要是从英文翻译过来的,原文地址http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/action-results 本文主要介绍ASP.NET WebAPI如何转换API返回值到HTTP响应消息的. 一个WebAPI可以返回下面类型中的一个: 1.void 2.HttpResponseMessage 3.IHttpActionResult 4.别的类型 更具上面的不同返回类型,WebAPI使用不同的

关于webapi 返回的类型的笔记

经过测试发现使用IE浏览器返回的数据是json,而使用Firefox和Chrome返回的则为xml,经研究发现IE在发生http请求时请求头accpet节点相比Firefox和Chrome缺少"application/xml" 类型,由于WebAPI返回数据为xml或json格式,IE没有发送可接受xml和json类型,所以默认为json格式数据,而Firefox和 chrome则发送了可接受xml类型,故返回了xml数据,下面是IE.Firefox和Chrome浏览器的请求头 浏览器

C# WebApi之接口返回类型详解

转自:https://www.cnblogs.com/hnsongbiao/p/9375888.html Webapi的接口返回值主要有四种类型 void无返回值 IHttpActionResult HttpResponseMessage 自定义类型 void无返回值 大家都知道void声明的是一个无返回值的方法,声明一个api控制器方法,例如: public class ValuesController : ApiController { [HttpGet] public void Get()

[经验分享]WebAPI中返回类型JsonMessage的应用

这是一个绝无仅有的好类型,一个你爱不释手的好类型,好了,不扯了,直接上干货. 相信大家都知道,在调用接口的时候返回Json数据已经成为一种不成文的标准,因为它的解析快,易读等优秀的特性,所以被绝大多数的程序猿们所喜爱. 今天就给大家介绍一种您可能忽略或者还不知道的返回类型JsonMessage 1 /// <summary> 2 /// 返回消息 3 /// </summary> 4 public class JsonMessage 5 { 6 /// <summary>

WebAPI 返回匿名类型

这是后台返回到前台的方法 public Object GetSomeThing() { return stubll.GetSomeThing(); } 在返回匿名类型时,通过Ajax可以直接获取到正确结果 但是当我直接在地址栏敲路径访问时,报错如下: "ObjectContent`1"类型未能序列化内容类型"application/xml; charset=utf-8"的响应正文. 我修改后台返回类型从Object换成IHttpActionResult,代码如下: