最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C# WebApi 接口返回值不困惑:返回值類(lèi)型詳解

 更新時(shí)間:2018年07月05日 10:02:43   作者:懶得安分  
這篇文章主要介紹了C# WebApi 接口返回值不困惑:返回值類(lèi)型詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

前言:已經(jīng)有一個(gè)月沒(méi)寫(xiě)點(diǎn)什么了,感覺(jué)心里空落落的。今天再來(lái)篇干貨,想要學(xué)習(xí)Webapi的園友們速速動(dòng)起來(lái),跟著博主一起來(lái)學(xué)習(xí)吧。之前分享過(guò)一篇C#進(jìn)階系列——WebApi接口傳參不再困惑:傳參詳解,這篇博文內(nèi)容本身很基礎(chǔ),沒(méi)想到引起很多園友關(guān)注,感謝大家的支持。作為程序猿,我們都知道參數(shù)和返回值是編程領(lǐng)域不可分割的兩大塊,此前分享了下WebApi的傳參機(jī)制,今天再來(lái)看看WebApi里面另一個(gè)重要而又基礎(chǔ)的知識(shí)點(diǎn):返回值。還是那句話:本篇針對(duì)初初使用WebApi的同學(xué)們,比較基礎(chǔ),有興趣的且看看。

使用過(guò)Webapi的園友應(yīng)該都知道,Webapi的接口返回值主要有四種類(lèi)型

  1. void無(wú)返回值
  2. IHttpActionResult
  3. HttpResponseMessage
  4. 自定義類(lèi)型

此篇就圍繞這四塊分別來(lái)看看它們的使用。

一、void無(wú)返回值

void關(guān)鍵字我們都不陌生,它申明方法沒(méi)有返回值。它的使用也很簡(jiǎn)單,我們來(lái)看一個(gè)示例就能明白。

public class ORDER
 {
  public string ID { get; set; }

  public string NO { get; set; }

  public string NAME { get; set; }

  public string DESC { get; set; }
 }
public class OrderController : ApiController
 {
  [HttpPost]
  public void SaveOrder(ORDER name)
  { 
   //處理業(yè)務(wù)邏輯

  }
 }

在Web里面調(diào)用

$(function () {
 $.ajax({
  type: 'post',
  url: 'http://localhost:21528/api/Order/SaveOrder',
  data: { ID: "aaa", NAME: "test" },
  success: function (data, status) {
   alert(data);
  }
 });
});

得到結(jié)果

可以看到,使用void申明的方法,在success方法里面得不到返回值,并且會(huì)返回http狀態(tài)碼204,告訴客戶端此請(qǐng)求沒(méi)有返回值。

二、IHttpActionResult

IHttpActionResult類(lèi)型是WebApi里面非常重要的一種返回值類(lèi)型。下面博主就根據(jù)平時(shí)在項(xiàng)目里面使用最多的幾種方式來(lái)講解下這種類(lèi)型的返回值的一些用法。

1、Json<T>(T content)

使用MVC開(kāi)發(fā)過(guò)的朋友一定記得,在MVC里面,請(qǐng)求數(shù)據(jù)的接口的返回值類(lèi)型大部分使用的是JsonResult,在MVC里面你一定也寫(xiě)過(guò)類(lèi)似這樣的接口:

 public JsonResult GetResult()
  {
   return Json(new { }, JsonRequestBehavior.AllowGet);
  }

那么,在WebAPI里面是否也存在類(lèi)似的用法呢。呵呵,在這點(diǎn)上面,微軟總是貼心的。在WebApi的ApiController這個(gè)抽象類(lèi)里面,為我們封裝了Json<T>(T content)這個(gè)方法,它的用法和MVC里面的JsonResult基本類(lèi)似。我們通過(guò)一個(gè)例子來(lái)說(shuō)明它的用法:

[HttpGet]
  public IHttpActionResult GetOrder()
  {
   var lstRes = new List<ORDER>(); 

   //實(shí)際項(xiàng)目中,通過(guò)后臺(tái)取到集合賦值給lstRes變量。這里只是測(cè)試。
   lstRes.Add(new ORDER() { ID = "aaaa", NO = "111", NAME = "111", DESC = "1111" });
   lstRes.Add(new ORDER() { ID = "bbbb", NO = "222", NAME = "222", DESC = "2222" });

   return Json<List<ORDER>>(lstRes);
  }

看到這個(gè)代碼,有人就疑惑了,我們定義的返回值類(lèi)型是IHttpActionResult類(lèi)型,直接返回Json<T>(T content)這樣可行么?我們將Json轉(zhuǎn)到定義看看:

 protected internal JsonResult<T> Json<T>(T content); 

我們繼續(xù)將JsonResult<T>轉(zhuǎn)到定義

原來(lái)JsonResult<T>是實(shí)現(xiàn)了IHttpActionResult接口的,難怪可以直接返回呢。

知道了這個(gè),我們直接在Web里面通過(guò)ajax請(qǐng)求來(lái)調(diào)用:

$(function () {
 $.ajax({
  type: 'get',
  url: 'http://localhost:21528/api/Order/GetOrder',
  data: {},
  success: function (data, status) {
   alert(data);
  }
 });
});

來(lái)看結(jié)果:

既然實(shí)體類(lèi)可以直接這樣傳遞,那么如果我們想要傳遞一些匿名類(lèi)型呢,因?yàn)楹芏嗲闆r下,我們需要返回到前端的對(duì)象都沒(méi)有對(duì)應(yīng)的實(shí)體來(lái)對(duì)應(yīng),如果我們想要返回匿名對(duì)象怎么辦呢?我們知道,這里的Json<T>(T content)必須要傳一個(gè)對(duì)應(yīng)的泛型類(lèi)型,如果是匿名類(lèi)型這里肯定不好傳。還好有我們的object類(lèi)型,當(dāng)然你可以使用dynamic,我們來(lái)試一把。

[HttpGet]
  public IHttpActionResult GetOrder()
  {
   
   return Json<dynamic>(new { AA = "", BB = "cc" });
  }

同樣的來(lái)看測(cè)試結(jié)果:

2、Ok()、Ok<T>(T content)

除了Json<T>(T content),在ApiController里面還有另外一個(gè)比較常用的方法:Ok()。同樣,我們將Ok()轉(zhuǎn)到定義

protected internal virtual OkResult Ok();

OkResult轉(zhuǎn)到定義

有了這個(gè)作為基礎(chǔ),我們就可以放心大膽的使用了。

 [HttpGet]
  public IHttpActionResult GetOKResult()
  {
   return Ok();
  }

得到結(jié)果

如果返回Ok(),就表示不向客戶端返回任何信息,只告訴客戶端請(qǐng)求成功。

除了Ok()之外,還有另外一個(gè)重載Ok<T>(T content)。

 [HttpGet]
  public IHttpActionResult GetOKResult(string name)
  {
   return Ok<string>(name);
  }

這種用法和Json<T>(T content)比較類(lèi)似,如果你非要問(wèn)這兩者有什么區(qū)別,或者說(shuō)怎么選擇兩者。那么我的理解是如果是返回實(shí)體或者實(shí)體集合,建議使用Json<T>(T content),如果是返回基礎(chǔ)類(lèi)型(如int、string等),使用Ok<T>(T content)。

3、NotFound()

當(dāng)需要向客戶端返回找不到記錄時(shí),有時(shí)需要用到NotFound()方法。

protected internal virtual NotFoundResult NotFound();

來(lái)看看它的使用場(chǎng)景

[HttpGet]
  public IHttpActionResult GetNotFoundResult(string id)
  {
   var lstRes = new List<ORDER>();

   //實(shí)際項(xiàng)目中,通過(guò)后臺(tái)取到集合賦值給lstRes變量。這里只是測(cè)試。
   lstRes.Add(new ORDER() { ID = "aaaa", NO = "111", NAME = "111", DESC = "1111" });
   lstRes.Add(new ORDER() { ID = "bbbb", NO = "222", NAME = "222", DESC = "2222" });
   var oFind = lstRes.FirstOrDefault(x => x.ID == id) ;
   if (oFind == null)
   {
    return NotFound();
   }
   else
   {
    return Json<ORDER>(oFind);
   }
  }

得到結(jié)果

NotFound()方法會(huì)返回一個(gè)404的錯(cuò)誤到客戶端。

4、其他

其他還有一些方法,都有它特定的用途。在此貼出來(lái)。

4.1、Content<T>(HttpStatusCode statusCode, T value)

 [HttpGet]
  public IHttpActionResult GetContentResult()
  {
   return Content<string>(HttpStatusCode.OK, "OK");
  }

向客戶端返回值和http狀態(tài)碼。

4.2、BadRequest()

[HttpGet]
  public IHttpActionResult GetBadRequest(ORDER order)
  {
   if (string.IsNullOrEmpty(order.ID))
    return BadRequest();
   return Ok();
  }

向客戶端返回400的http錯(cuò)誤。

4.3、Redirect(string location)

 [HttpGet]
  public IHttpActionResult RedirectResult()
  {
   return Redirect("http://localhost:21528/api/Order/GetContentResult");
  }

將請(qǐng)求重定向到其他地方。

5、自定義IHttpActionResult接口的實(shí)現(xiàn)

上面介紹了一些系統(tǒng)內(nèi)置的常用的實(shí)現(xiàn)IHttpActionResult接口的方法。如果我們需要自定義IHttpActionResult的返回呢?

在介紹之前,我們有必要先來(lái)看看IHttpActionResult類(lèi)型的定義,將IHttpActionResult轉(zhuǎn)到定義可以看到:

namespace System.Web.Http
{
 // 摘要: 
 //  Defines a command that asynchronously creates an System.Net.Http.HttpResponseMessage.
 public interface IHttpActionResult
 {
  // 摘要: 
  //  Creates an System.Net.Http.HttpResponseMessage asynchronously.
  //
  // 參數(shù): 
  // cancellationToken:
  //  The token to monitor for cancellation requests.
  //
  // 返回結(jié)果: 
  //  A task that, when completed, contains the System.Net.Http.HttpResponseMessage.
  Task<System.Net.Http.HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken);
 }
}

這個(gè)接口包含唯一的一個(gè)方法ExecuteAsync(),此方法將以異步方式創(chuàng)建一個(gè)HttpResponseMessage實(shí)例返回給客戶端。

有了這個(gè)作為基礎(chǔ),下面,我們自定義一個(gè)bootstrapTable服務(wù)端分頁(yè)的子類(lèi)去展示自定義IHttpActionResult的用法。

首先,自定義一個(gè)實(shí)現(xiàn)類(lèi)

public class PageResult : IHttpActionResult
 {
  object _value;
  HttpRequestMessage _request;

  public PageResult(object value, HttpRequestMessage request)
  {
   _value = value;
   _request = request;
  }

  public Task<HttpResponseMessage> ExecuteAsync(System.Threading.CancellationToken cancellationToken)
  {
   var response = new HttpResponseMessage()
   {
    Content = new ObjectContent(typeof(object), _value, new JsonMediaTypeFormatter()),
    RequestMessage = _request
   };
   return Task.FromResult(response);
  }
 }

然后,在API接口里面返回PageResult對(duì)象

[HttpGet]
  public IHttpActionResult GetPageRow(int limit, int offset)
  {
   var lstRes = new List<ORDER>();

   //實(shí)際項(xiàng)目中,通過(guò)后臺(tái)取到集合賦值給lstRes變量。這里只是測(cè)試。
   lstRes.Add(new ORDER() { ID = "aaaa", NO = "111", NAME = "111", DESC = "1111" });
   lstRes.Add(new ORDER() { ID = "bbbb", NO = "222", NAME = "222", DESC = "2222" });

   var oData = new { total = lstRes.Count, rows = lstRes.Skip(offset).Take(limit).ToList() };
   return new PageResult(oData, Request);
  }

最好,ajax調(diào)用

$(function () {
 $.ajax({
  type: 'get',
  url: 'http://localhost:21528/api/Order/GetPageRow',
  data: { limit:1,offset:1},
  success: function (data, status) {
   alert(data);
  }
 });
});

得到結(jié)果

三、HttpResponseMessage

在上文自定義IHttpActionResult返回類(lèi)型的時(shí)候,提到過(guò)HttpResponseMessage這個(gè)對(duì)象。它表示向客戶端返回一個(gè)http響應(yīng)的消息對(duì)象(包含http狀態(tài)碼和需要返回客戶端的消息)。這個(gè)對(duì)象也有它獨(dú)特的使用場(chǎng)景:需要向客戶端返回HttpResponse時(shí)就要用到這個(gè)對(duì)象。以導(dǎo)出為例,由于需要將導(dǎo)出的Excel文件輸出到客戶端瀏覽器,Webapi的服務(wù)端需要向Web的客戶端輸出文件流,這個(gè)時(shí)候一般的IHttpActionResult對(duì)象不方便解決這個(gè)問(wèn)題,于是HttpReponseMessage派上了用場(chǎng)。我們來(lái)看看它的使用示例。

public HttpResponseMessage Export()
  {
   //取數(shù)據(jù)
   var lstRes = OrderBLL.Export();

   //向Excel里面填充數(shù)據(jù)
   HSSFWorkbook workbook = new HSSFWorkbook();
   CreateAndFillSheet(workbook, lstRes);
   
   //保存到服務(wù)
   var fileName = "Excel" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xls";
   var strPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Data\" + fileName);
   using (FileStream fs = new FileStream(strPath, FileMode.Create))
   {
    workbook.Write(fs);
    using (MemoryStream ms = new MemoryStream())
    {
     workbook.Write(ms);
    }
   }

   //輸出到瀏覽器
   try
   {
    var stream = new FileStream(strPath, FileMode.Open);
    HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
    response.Content = new StreamContent(stream);
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
    response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
    {
     FileName = fileName
    };

    return response;
   }
   catch
   {
    return new HttpResponseMessage(HttpStatusCode.NoContent);
   }
  }

將文件流保存在StreamContent對(duì)象里面,然后輸出到瀏覽器。在瀏覽器端即可將Excel輸出。

四、自定義類(lèi)型

以上幾種返回值類(lèi)型能解決我們大部分返回值的問(wèn)題,當(dāng)然,你也可以將webapi的接口和普通方法一樣,返回任意的類(lèi)型,WebApi會(huì)自動(dòng)序列化你自定義任何返回類(lèi)型,然后將序列化的值寫(xiě)到響應(yīng)正文里,狀態(tài)碼統(tǒng)一返回200。比如:

[HttpGet]
  public object GetOther()
  {
   var lstRes = new List<ORDER>();

   //實(shí)際項(xiàng)目中,通過(guò)后臺(tái)取到集合賦值給lstRes變量。這里只是測(cè)試。
   lstRes.Add(new ORDER() { ID = "aaaa", NO = "111", NAME = "111", DESC = "1111" });
   lstRes.Add(new ORDER() { ID = "bbbb", NO = "222", NAME = "222", DESC = "2222" });

   return lstRes;
  }

得到結(jié)果

和上面的Json、Ok等用法在效果上面沒(méi)有太大區(qū)別。

五、總結(jié)

以上通過(guò)四個(gè)方面詳細(xì)分享了下WebApi里面返回值的常見(jiàn)用法,不能說(shuō)哪種方式最好,因?yàn)槊糠N方式都有其特定的使用場(chǎng)景。博主覺(jué)得為了規(guī)范WebApi接口,對(duì)于一般接口的返回值,盡量使用IHttpActionResult類(lèi)型作為返回值,畢竟是微軟內(nèi)置的東西,可能為我們考慮了很多我們考慮不到的東西。當(dāng)然,你可能會(huì)覺(jué)得麻煩,你可能會(huì)說(shuō)直接和普通方法一樣來(lái)使用不是更爽,博主當(dāng)初也有這種想法,可是學(xué)習(xí)微軟的東西多了之后發(fā)現(xiàn)很多東西還是遵守一定的標(biāo)準(zhǔn)比較好,至少維護(hù)起來(lái)方便。這就像博主最近正在努力學(xué)習(xí)的WebApi+oData一樣,為什么要搞這么一套標(biāo)準(zhǔn)性的東西,還不是為了更加方便地規(guī)范Restful風(fēng)格。也希望大家多多支持腳本之家。

相關(guān)文章

  • Unity3d實(shí)現(xiàn)Flappy Bird游戲

    Unity3d實(shí)現(xiàn)Flappy Bird游戲

    這篇文章主要為大家詳細(xì)介紹了Unity3d實(shí)現(xiàn)Flappy Bird游戲,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • C#調(diào)用存儲(chǔ)過(guò)程詳解(帶返回值、參數(shù)輸入輸出等)

    C#調(diào)用存儲(chǔ)過(guò)程詳解(帶返回值、參數(shù)輸入輸出等)

    這篇文章主要介紹了C#調(diào)用存儲(chǔ)過(guò)程的方法,結(jié)合實(shí)例形式詳細(xì)分析了各種常用的存儲(chǔ)過(guò)程調(diào)用方法,包括帶返回值、參數(shù)輸入輸出等,需要的朋友可以參考下
    2016-06-06
  • C#中實(shí)現(xiàn)CAN通信的使用

    C#中實(shí)現(xiàn)CAN通信的使用

    本文主要介紹了C#中實(shí)現(xiàn)CAN通信的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-04-04
  • 利用C#代碼實(shí)現(xiàn)圖片旋轉(zhuǎn)360度

    利用C#代碼實(shí)現(xiàn)圖片旋轉(zhuǎn)360度

    本文介紹利用C#代碼實(shí)現(xiàn)圖片旋轉(zhuǎn)360度,具體實(shí)例代碼已附上,僅供大家參考,希望對(duì)大家有所幫助
    2016-11-11
  • C#計(jì)算文件MD5校驗(yàn)的方法

    C#計(jì)算文件MD5校驗(yàn)的方法

    這篇文章主要介紹了C#計(jì)算文件MD5校驗(yàn)的方法,涉及C#針對(duì)文件進(jìn)行md5校驗(yàn)的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-04-04
  • c# 曲線圖生成代碼

    c# 曲線圖生成代碼

    c# 曲線圖生成代碼,需要的朋友可以參考下。
    2011-07-07
  • C#計(jì)算矩陣的逆矩陣方法實(shí)例分析

    C#計(jì)算矩陣的逆矩陣方法實(shí)例分析

    這篇文章主要介紹了C#計(jì)算矩陣的逆矩陣方法,較為詳細(xì)的分析了逆矩陣的計(jì)算原理與相關(guān)的C#實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-08-08
  • C#入門(mén)學(xué)習(xí)之集合、比較和轉(zhuǎn)換

    C#入門(mén)學(xué)習(xí)之集合、比較和轉(zhuǎn)換

    本文詳細(xì)講解了C#中的集合、比較和轉(zhuǎn)換,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • c#基礎(chǔ)系列之值類(lèi)型和引用類(lèi)型的深入理解

    c#基礎(chǔ)系列之值類(lèi)型和引用類(lèi)型的深入理解

    這篇文章主要給大家介紹了關(guān)于c#基礎(chǔ)系列之值類(lèi)型和引用類(lèi)型的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-09-09
  • C#中使用CAS實(shí)現(xiàn)無(wú)鎖算法的示例詳解

    C#中使用CAS實(shí)現(xiàn)無(wú)鎖算法的示例詳解

    CAS(Compare-and-Swap)是一種多線程并發(fā)編程中常用的原子操作,用于實(shí)現(xiàn)多線程間的同步和互斥訪問(wèn)。本文將利用CAS實(shí)現(xiàn)無(wú)鎖算法,需要的可以參考一下
    2023-04-04

最新評(píng)論

远安县| 丹阳市| 青河县| 城固县| 永昌县| 深水埗区| 海阳市| 濮阳县| 武川县| 嘉荫县| 成都市| 上饶县| 白沙| 弥勒县| 明溪县| 噶尔县| 彭阳县| 噶尔县| 邵东县| 定襄县| 长宁区| 芒康县| 长海县| 马鞍山市| 错那县| 马公市| 二手房| 晋江市| 永济市| 东阳市| 诸城市| 宜兰市| 时尚| 什邡市| 磴口县| 昔阳县| 巨鹿县| 青铜峡市| 宁德市| 剑川县| 崇仁县|