亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C# WebApi 接口返回值不困惑:返回值類型詳解

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

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

使用過Webapi的園友應該都知道,Webapi的接口返回值主要有四種類型

  1. void無返回值
  2. IHttpActionResult
  3. HttpResponseMessage
  4. 自定義類型

此篇就圍繞這四塊分別來看看它們的使用。

一、void無返回值

void關鍵字我們都不陌生,它申明方法沒有返回值。它的使用也很簡單,我們來看一個示例就能明白。

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è)務邏輯

  }
 }

在Web里面調用

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

得到結果

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

二、IHttpActionResult

IHttpActionResult類型是WebApi里面非常重要的一種返回值類型。下面博主就根據平時在項目里面使用最多的幾種方式來講解下這種類型的返回值的一些用法。

1、Json<T>(T content)

使用MVC開發(fā)過的朋友一定記得,在MVC里面,請求數據的接口的返回值類型大部分使用的是JsonResult,在MVC里面你一定也寫過類似這樣的接口:

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

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

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

   //實際項目中,通過后臺取到集合賦值給lstRes變量。這里只是測試。
   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);
  }

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

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

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

原來JsonResult<T>是實現了IHttpActionResult接口的,難怪可以直接返回呢。

知道了這個,我們直接在Web里面通過ajax請求來調用:

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

來看結果:

既然實體類可以直接這樣傳遞,那么如果我們想要傳遞一些匿名類型呢,因為很多情況下,我們需要返回到前端的對象都沒有對應的實體來對應,如果我們想要返回匿名對象怎么辦呢?我們知道,這里的Json<T>(T content)必須要傳一個對應的泛型類型,如果是匿名類型這里肯定不好傳。還好有我們的object類型,當然你可以使用dynamic,我們來試一把。

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

同樣的來看測試結果:

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

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

protected internal virtual OkResult Ok();

OkResult轉到定義

有了這個作為基礎,我們就可以放心大膽的使用了。

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

得到結果

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

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

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

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

3、NotFound()

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

protected internal virtual NotFoundResult NotFound();

來看看它的使用場景

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

   //實際項目中,通過后臺取到集合賦值給lstRes變量。這里只是測試。
   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);
   }
  }

得到結果

NotFound()方法會返回一個404的錯誤到客戶端。

4、其他

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

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錯誤。

4.3、Redirect(string location)

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

將請求重定向到其他地方。

5、自定義IHttpActionResult接口的實現

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

在介紹之前,我們有必要先來看看IHttpActionResult類型的定義,將IHttpActionResult轉到定義可以看到:

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.
  //
  // 參數: 
  // cancellationToken:
  //  The token to monitor for cancellation requests.
  //
  // 返回結果: 
  //  A task that, when completed, contains the System.Net.Http.HttpResponseMessage.
  Task<System.Net.Http.HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken);
 }
}

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

有了這個作為基礎,下面,我們自定義一個bootstrapTable服務端分頁的子類去展示自定義IHttpActionResult的用法。

首先,自定義一個實現類

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對象

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

   //實際項目中,通過后臺取到集合賦值給lstRes變量。這里只是測試。
   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調用

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

得到結果

三、HttpResponseMessage

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

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

   //向Excel里面填充數據
   HSSFWorkbook workbook = new HSSFWorkbook();
   CreateAndFillSheet(workbook, lstRes);
   
   //保存到服務
   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對象里面,然后輸出到瀏覽器。在瀏覽器端即可將Excel輸出。

四、自定義類型

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

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

   //實際項目中,通過后臺取到集合賦值給lstRes變量。這里只是測試。
   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;
  }

得到結果

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

五、總結

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

相關文章

  • C#判斷單詞個數方法總結

    C#判斷單詞個數方法總結

    我們給大家總計了C#中判斷英文單詞個數的方法以及排序的技巧,對此有需要的朋友可以測試下。
    2018-03-03
  • C#基礎教程之類class與結構struct的區(qū)別

    C#基礎教程之類class與結構struct的區(qū)別

    struct是值類型,創(chuàng)建一個struct類型的實例被分配在棧上,class是引用類型,創(chuàng)建一個class類型實例被分配在托管堆上,下面這篇文章主要給大家介紹了關于C#基礎教程之類class與結構struct區(qū)別的相關資料,需要的朋友可以參考下
    2022-11-11
  • C#開發(fā)Winform程序調用存儲過程

    C#開發(fā)Winform程序調用存儲過程

    這篇文章介紹了C#開發(fā)Winform程序調用存儲過程的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • C#排序算法之快速排序

    C#排序算法之快速排序

    下面給出的代碼是以數組最后一個元素作為參考元素,這僅是參考元素選取的方式之一。
    2010-09-09
  • c# 生成二維碼的示例

    c# 生成二維碼的示例

    這篇文章主要介紹了c# 生成二維碼的示例,幫助大家更好的理解和使用c#編程語言,感興趣的朋友可以了解下
    2020-11-11
  • Winform使用DataGridView實現下拉篩選

    Winform使用DataGridView實現下拉篩選

    這篇文章主要為大家詳細介紹了Winform如何使用原生DataGridView實現下拉篩選功能,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起了解一下
    2023-09-09
  • C#使用SignalR實現與前端vue實時通信的示例代碼

    C#使用SignalR實現與前端vue實時通信的示例代碼

    SignalR 是 ASP.NET Core 的一個庫,它簡化了在應用程序中添加實時通信的過程,無論是聊天應用、實時游戲還是協作工具,SignalR 都能提供高效且易于實現的解決方案,本文給大家介紹了C#使用SignalR實現與前端vue實時通信的實現,需要的朋友可以參考下
    2024-10-10
  • C#利用FluentFTP實現FTP上傳下載功能詳解

    C#利用FluentFTP實現FTP上傳下載功能詳解

    FTP作為日常工作學習中,非常重要的一個文件傳輸存儲空間,想必大家都非常的熟悉了,那么如何快速的實現文件的上傳下載功能呢,本文以一個簡單的小例子,簡述如何通過FluentFTP實現文件的上傳和下載功能
    2023-02-02
  • C# 使用Microsoft Edge WebView2的相關總結

    C# 使用Microsoft Edge WebView2的相關總結

    這篇文章主要介紹了C# 使用Microsoft Edge WebView2的相關總結,幫助大家更好的理解和學習使用c#,感興趣的朋友可以了解下
    2021-02-02
  • C#在驗證文件共享模式下實現多線程文件寫入

    C#在驗證文件共享模式下實現多線程文件寫入

    這篇文章主要為大家詳細介紹了C#在驗證文件共享模式下實現多線程文件寫入的相關知識,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下
    2024-01-01

最新評論