一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C# - C# WebApi 接口返回值不困惑:返回值類型詳解

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

2022-02-25 14:15懶得安分 C#

這篇文章主要介紹了C# WebApi 接口返回值不困惑:返回值類型詳解,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

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

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

  1. void無返回值
  2. ihttpactionresult
  3. httpresponsemessage
  4. 自定義類型

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

一、void無返回值

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

?
1
2
3
4
5
6
7
8
9
10
public class order
 {
  public string id { get; set; }
 
  public string no { get; set; }
 
  public string name { get; set; }
 
  public string desc { get; set; }
 }
?
1
2
3
4
5
6
7
8
9
public class ordercontroller : apicontroller
 {
  [httppost]
  public void saveorder(order name)
  {
   //處理業務邏輯
 
  }
 }

在web里面調用

?
1
2
3
4
5
6
7
8
9
10
$(function () {
 $.ajax({
  type: 'post',
  url: 'http://localhost:21528/api/order/saveorder',
  data: { id: "aaa", name: "test" },
  success: function (data, status) {
   alert(data);
  }
 });
});

得到結果

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

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

二、ihttpactionresult

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

1、json<t>(t content)

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

?
1
2
3
4
public jsonresult getresult()
 {
  return json(new { }, jsonrequestbehavior.allowget);
 }

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

?
1
2
3
4
5
6
7
8
9
10
11
[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轉到定義看看:

?
1
protected internal jsonresult<t> json<t>(t content);

我們繼續將jsonresult<t>轉到定義

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

原來jsonresult<t>是實現了ihttpactionresult接口的,難怪可以直接返回呢。

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

?
1
2
3
4
5
6
7
8
9
10
$(function () {
 $.ajax({
  type: 'get',
  url: 'http://localhost:21528/api/order/getorder',
  data: {},
  success: function (data, status) {
   alert(data);
  }
 });
});

來看結果:

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

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

?
1
2
3
4
5
6
[httpget]
  public ihttpactionresult getorder()
  {
   
   return json<dynamic>(new { aa = "", bb = "cc" });
  }

同樣的來看測試結果:

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

2、ok()、ok<t>(t content)

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

?
1
protected internal virtual okresult ok();

okresult轉到定義

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

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

?
1
2
3
4
5
[httpget]
 public ihttpactionresult getokresult()
 {
  return ok();
 }

得到結果

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

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

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

?
1
2
3
4
5
[httpget]
 public ihttpactionresult getokresult(string name)
 {
  return ok<string>(name);
 }

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

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

3、notfound()

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

?
1
protected internal virtual notfoundresult notfound();

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

來看看它的使用場景

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[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);
   }
  }

得到結果

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

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

4、其他

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

4.1、content<t>(httpstatuscode statuscode, t value)

?
1
2
3
4
5
[httpget]
 public ihttpactionresult getcontentresult()
 {
  return content<string>(httpstatuscode.ok, "ok");
 }

向客戶端返回值和http狀態碼。

4.2、badrequest()

?
1
2
3
4
5
6
7
[httpget]
  public ihttpactionresult getbadrequest(order order)
  {
   if (string.isnullorempty(order.id))
    return badrequest();
   return ok();
  }

向客戶端返回400的http錯誤。

4.3、redirect(string location)

?
1
2
3
4
5
[httpget]
 public ihttpactionresult redirectresult()
 {
  return redirect("http://localhost:21528/api/order/getcontentresult");
 }

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

5、自定義ihttpactionresult接口的實現

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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(),此方法將以異步方式創建一個httpresponsemessage實例返回給客戶端。

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

首先,自定義一個實現類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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對象

?
1
2
3
4
5
6
7
8
9
10
11
12
[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調用

?
1
2
3
4
5
6
7
8
9
10
$(function () {
 $.ajax({
  type: 'get',
  url: 'http://localhost:21528/api/order/getpagerow',
  data: { limit:1,offset:1},
  success: function (data, status) {
   alert(data);
  }
 });
});

得到結果

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

三、httpresponsemessage

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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會自動序列化你自定義任何返回類型,然后將序列化的值寫到響應正文里,狀態碼統一返回200。比如:

?
1
2
3
4
5
6
7
8
9
10
11
[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;
  }

得到結果

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

和上面的json、ok等用法在效果上面沒有太大區別。

五、總結

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

原文鏈接:http://www.cnblogs.com/landeanfen/p/5501487.html

延伸 · 閱讀

精彩推薦
  • C#C#裁剪,縮放,清晰度,水印處理操作示例

    C#裁剪,縮放,清晰度,水印處理操作示例

    這篇文章主要為大家詳細介紹了C#裁剪,縮放,清晰度,水印處理操作示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    吳 劍8332021-12-08
  • C#深入解析C#中的交錯數組與隱式類型的數組

    深入解析C#中的交錯數組與隱式類型的數組

    這篇文章主要介紹了深入解析C#中的交錯數組與隱式類型的數組,隱式類型的數組通常與匿名類型以及對象初始值設定項和集合初始值設定項一起使用,需要的...

    C#教程網6172021-11-09
  • C#C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    這篇文章主要介紹了C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題,簡單描述了訪問者模式的定義并結合具體實例形式分析了C#使用訪問者模式解決長...

    GhostRider9502022-01-21
  • C#C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    這篇文章主要介紹了C# 實現對PPT文檔加密、解密及重置密碼的操作方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下...

    E-iceblue5012022-02-12
  • C#Unity3D實現虛擬按鈕控制人物移動效果

    Unity3D實現虛擬按鈕控制人物移動效果

    這篇文章主要為大家詳細介紹了Unity3D實現虛擬按鈕控制人物移動效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一...

    shenqingyu060520232410972022-03-11
  • C#WPF 自定義雷達圖開發實例教程

    WPF 自定義雷達圖開發實例教程

    這篇文章主要介紹了WPF 自定義雷達圖開發實例教程,本文介紹的非常詳細,具有參考借鑒價值,需要的朋友可以參考下...

    WinterFish13112021-12-06
  • C#C#實現XML文件讀取

    C#實現XML文件讀取

    這篇文章主要為大家詳細介紹了C#實現XML文件讀取的相關代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    Just_for_Myself6702022-02-22
  • C#C#通過KD樹進行距離最近點的查找

    C#通過KD樹進行距離最近點的查找

    這篇文章主要為大家詳細介紹了C#通過KD樹進行距離最近點的查找,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    帆帆帆6112022-01-22
主站蜘蛛池模板: 美妇在男人胯下哀求 | 国产一级毛片国语版 | 动漫人物差差差动漫人物免费观看 | 曹逼网站 | 我们中文在线观看免费完整版 | japan日韩xxxx69hd japanese在线观看 | 亚洲一区二区三区深夜天堂 | 丫鬟粗大狠狠贯穿h | 久草草在线视视频 | 国产高清在线不卡 | 小草高清视频免费直播 | jux629三浦理惠子在线播放 | 亚洲一二区视频 | 青青草原网| 操操小说| 韩国甜性涩爱在线播放 | 精品视频久久久久 | 性柔术18性13处交 | 亚洲国产精品综合久久一线 | chinses台湾男同志hd | 精品一区二区三区视频日产 | 亚洲欧美日韩特级毛片 | 狠狠色综合久久婷婷 | 精品视频久久久久 | 亚洲免费精品 | 好姑娘在线完整版视频 | 久久精品国产色蜜蜜麻豆国语版 | 性啪啪chinese东北女人 | av魔镜收集号 | 欧美综合另类 | 欧美一级片免费看 | 国产成人亚洲综合a∨婷婷 国产成人亚洲精品乱码在线观看 | 国产肥女bbwbbw | 我强进了老师身体在线观看 | 日韩精品一区二区三区中文在线 | 被强上后我成瘾了小说 | 国产rpg迷雾之风冷狐破解 | 国产区成人综合色在线 | 大桥未久midd—962在线 | 国产欧美日韩图片一区二区 | 久久受www免费人成_看片中文 |