格式化資料這東西,主要看需要的運用場景,今天和大家分享的是webapi格式化資料,這裡面的例子主要是輸出json和xml的格式資料,測試用例很接近實際常用情況;希望大家喜歡,也希望各位多多掃碼支援和點贊謝謝:
. 自定義一個Action,響應輸出集合資料
. api返回json資料的兩種方式
. json時間格式處理方式
. 讓api介面支援返回json和xml資料
下面一步一個腳印的來分享:
. 自定義一個Action,響應輸出集合資料
首先,我們新建一個webapi專案,新建好以後我們能夠找到 Controllers/ValuesController.cs 檔案,檢視裡面有自動生成的一些程式碼,我們先不管;然後我們建立一個學生 MoStudent 類,屬性程式碼如:
1 public class MoStudent 2 { 3 public DateTime Birthday { get; set; } 4 5 public int Id { get; set; } 6 7 public string Name { get; set; } 8 9 public bool Sex { get; set; } 11 }
然後我們在 ValuesController 中初始化一些公共的資料,程式碼如:
1 public List<MoStudent> students = new List<MoStudent>() { 2 3 new MoStudent{ Id =1 , Name ="小1", Sex = true, Birthday= Convert.ToDateTime("1991-05-31")}, 4 new MoStudent{ Id =2 , Name ="小2", Sex = false, Birthday= Convert.ToDateTime("1991-05-31")}, 5 new MoStudent{ Id =3 , Name ="小3", Sex = false, Birthday= Convert.ToDateTime("1991-05-31")}, 6 new MoStudent{ Id =4 , Name ="小4", Sex = true, Birthday= Convert.ToDateTime("1991-05-31")} 7 };
再來,我們新建立一個 GetAllStudents01() 方法,並輸出學生集合資料,程式碼如:
1 public List<MoStudent> GetAllStudents01() 2 { 3 return students; 4 }
這個時候我們生成一下專案,然後在瀏覽器訪問下地址為: http://localhost:1001/api/values ,此時會提示一個錯誤資訊:
這個錯誤資訊是該地址同時匹配上了兩個api的Action,分別為 Get()和GetAllStudents01() 兩個方法,這種錯誤我們應該怎麼處理呢;一種可以刪除其中一個方法;二種方式是在預設路由設定下Action,然後通過具體的Controller/Action地址來訪問;三種是通過Route修改下對應的訪問路由(這種方法前面一篇文章已經有說明);這裡我們就使用第二種,先來修改下 WebApiConfig.cs 檔案中預設路由的配置,修改後的配置如:
1 config.Routes.MapHttpRoute( 2 name: "DefaultApi", 3 routeTemplate: "api/{controller}/{action}/{id}", 4 defaults: new { id = RouteParameter.Optional } 5 );
生成後,我們在瀏覽器中這樣訪問: http://localhost:1001/api/values/GetAllStudents01 ,GetAllStudents01是對應要訪問的Action名稱,不出意外我們能在瀏覽器中看到如下結果:
webapi能正常返回資料了,但是地址感覺好長的樣子,不利於我們測試,那麼下麼我們使用上一篇文章用到的標記RoutePrefix和Route來變動下路由,增加的程式碼如:
然後我們測試訪問下該地址: http://localhost:1001/s/all01 能正常返回如上面的截圖資料;
. api返回json資料的兩種方式
首先,我們回顧下看下上面節點例子的截圖,介面響應輸出的是xml格式的資料,這裡預設採用的是webapi自帶的xml格式化方式,把 Student 屬性全部展示了出來,我們真實開發介面的時候,通常會有些物件的屬性不會展示,下面我們通過增加 DataContract 和 DataMember 來設定把不需要暴露的屬性“隱藏掉”,我們先來看先增加了這兩個標記後的Student實體:
1 [DataContract] 2 public class MoStudent 3 { 4 [DataMember] 5 public DateTime Birthday { get; set; } 6 7 [DataMember] 8 public int Id { get; set; } 9 10 [DataMember] 11 public string Name { get; set; } 12 13 [DataMember] 14 public bool Sex { get; set; } 15 16 }
然後咋們執行下程式,在頁面看到的結果資訊和之前的結果一模一樣:
下面把 Birthday 屬性上面的 DataMember 去掉,然後再來執行檢視結果:
可以看到輸出的結果中已經沒有了這個 Birthday ,這裡能看出的結果是如果未標記 DataMember ,那麼是不會輸出來的;我們再來看一個有用的東西,先吧Birthday的DataMember回覆,然後修改成如下程式碼:
1 [DataContract] 2 public class MoStudent 3 { 4 [DataMember(Order = 3)] 5 public DateTime Birthday { get; set; } 6 7 [DataMember(Order = 0)] 8 public int Id { get; set; } 9 10 [DataMember(Order = 1)] 11 public string Name { get; set; } 12 13 [DataMember(Order = 2)] 14 public bool Sex { get; set; } 15 16 }
然後咋們再執行起來看效果圖:
相信仔細的朋友能夠發現,此時Birthday資料暫時的位置已經從第一個變到了最後一個,沒錯這就是DataMember中Order屬性引數的效果:用來指定顯示輸出資料的位置;
好了咋們來看正題,webapi返回json資料這裡講解兩種,一種是使用自帶的Json格式化方式,使用方法只需要在 Global.asax.cs 檔案中清除一下預設的xml輸出方式即可,程式碼如:
1 var format = GlobalConfiguration.Configuration.Formatters; 2 //清除預設xml 3 format.XmlFormatter.SupportedMediaTypes.Clear();
因為webapi在啟動的時候,預設格式化資料有兩種方式xml和json,而xml是其預設的啟動方式,所以這裡是需要清除了xml格式化,那麼另外只剩下json,所以咋們在執行程式後能看到這樣的結果輸出:
結果返回了json資料,如果咋們想要如上面xml一樣吧Birthday隱藏掉,我們同樣也可以使用 DataContract 和 DataMember 來做這效果,刪除Birthday對應的 DataMember 標記後,咋們能看到這樣的效果:
同理,我們把Birthday的DataMember還原,然後指定Order屬性值 [DataMember(Order=1)] ,這樣Birthday顯示的位置就變動了:
好了這試第一種json格式化的方式,下面來看下用使用Json.Net怎麼來格式化,為了避免影響效果,我們把 Global.asax.cs 檔案還原,然後重新增加一個Action方法,程式碼如:
1 [Route("all01_1")] 2 public async Task<HttpResponseMessage> GetAllStudents01_1() 3 { 4 var result = await JsonConvert.SerializeObjectAsync(students); 5 6 return new HttpResponseMessage 7 { 8 Content = new StringContent(result), 9 StatusCode = HttpStatusCode.OK 10 }; 11 }
這裡用到了Json.Net的 JsonConvert.SerializeObjectAsync 方法來格式化成字串,然後傳遞給 HttpResponseMessage ,最終輸出的效果和上面一樣,好了咋們也來看看這種方式怎麼來隱藏不希望介面暴露的屬性,這裡我們用 JsonIgnore 標記,測試用例在實體類中修改如:
1 [JsonIgnore] 2 public DateTime Birthday { get; set; }
然後執行看一下效果:
我們再來看一下怎麼來設定屬性的排序,可以使用 JsonProperty(Order = 1) ,實體類修改的程式碼如下:
1 public class MoStudent 2 { 3 //[DataMember(Order = 1)] 4 [JsonProperty(Order = 1)] 5 public DateTime Birthday { get; set; } 6 7 //[DataMember(Order = 0)] 8 [JsonProperty(Order = 0)] 9 public int Id { get; set; } 10 11 //[DataMember(Order = 1)] 12 [JsonProperty(Order = 1)] 13 public string Name { get; set; } 14 15 //[DataMember(Order = 2)] 16 [JsonProperty(Order = 2)] 17 public bool Sex { get; set; } 18 19 }
能得到和DataMember設定的一樣的結果:
. json時間格式處理方式
要說時間格式化,我們通常的生日格式如:yyyy-MM-dd這樣,下面也分別對剛才上面兩種json化出來的時間做格式化;先來看Json.net,我們先來定義一個名稱為 SelfDateTimeFormat 的類並且繼承 DateTimeConverterBase 類,然後需要重寫 ReadJson和WriteJson ,下面看下這個類的全部方法:
1 /// <summary> 2 /// 自定義時間格式化 3 /// </summary> 4 public class SelfDateTimeFormat : DateTimeConverterBase 5 { 6 public IsoDateTimeConverter TimeConvert = null; 7 8 public SelfDateTimeFormat() { 9 10 TimeConvert = new IsoDateTimeConverter 11 { 12 DateTimeFormat = "yyyy-MM-dd" 13 }; 14 } 15 16 public SelfDateTimeFormat(string formatter = "yyyy-MM-dd HH:mm:ss") 17 { 18 19 TimeConvert = new IsoDateTimeConverter 20 { 21 DateTimeFormat = formatter 22 }; 23 } 24 25 public override object ReadJson(Newtonsoft.Json.JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) 26 { 27 28 return TimeConvert.ReadJson(reader, objectType, existingValue, serializer); 29 } 30 31 public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) 32 { 33 34 TimeConvert.WriteJson(writer, value, serializer); 35 } 36 }
然後我們需要在實體類的時間屬性上增加這樣的標記: [JsonConverter(typeof(OverridClass.SelfDateTimeFormat))] ,這裡的 SelfDateTimeFormat 就是咋們剛才定義的自定義格式化時間類,我們來看一下輸出的效果資料:
好了,咋們再來看webapi自帶的json格式化如何定義一個日期格式的資料,我們需要在Global.asax.cs中增加如下程式碼:
1 var format = GlobalConfiguration.Configuration.Formatters; 2 format.JsonFormatter.SerializerSettings.DateFormatString = "yyyy.MM.dd";
沒錯,只需要如此簡單的程式碼,即可時間格式化成:
. 讓api介面支援返回json和xml資料
開篇第一小節已經有簡單說明webapi有自己的json和xml格式化處理,這裡們來設定通過引數請求返回不同的資料格式;首先還是需要在Global中設定如下程式碼:
1 var format = GlobalConfiguration.Configuration.Formatters; 2 format.JsonFormatter.SerializerSettings.DateFormatString = "yyyy.MM.dd"; 3 4 //清除預設xml 5 format.XmlFormatter.SupportedMediaTypes.Clear(); 6 7 //通過引數設定返回格式 8 format.JsonFormatter.MediaTypeMappings.Add(new QueryStringMapping("t", "json", "application/json")); 9 format.XmlFormatter.MediaTypeMappings.Add(new QueryStringMapping("t", "xml", "application/xml"));
這裡用到了 QueryStringMapping 類,並傳遞給他建構函式的引數 new QueryStringMapping("t", "json", "application/json") 和 new QueryStringMapping("t", "xml", "application/xml") 這樣就分別對用了json和xml,而前面的“t”表示請求的url地址中引數名稱t,下面我們分別來測試下兩種請求的引數,地址分別為:
http://localhost:1001/s/all01?t=xml
http://localhost:1001/s/all01?t=json
好了,本篇的內容就和大家分享到這裡,例子個人感覺很接近實際常用,如果可以希望您點個贊,謝謝。