[C#]API 傳 IPagedList物件 無法成功轉為JsonString
問題:
之前在實作一個前後端分離的專案,實作的內容大概是這樣,前台傳給API端一個查詢條件,而API端須回傳一個「IPagedList」類別的列表資訊。不過卻在實作時發生問題,IPagedList一直無法成功序列化為Json String。
解決方法:
(一)序列化 IPagedList
其實像「IPagedList」這種介面,或者是EF物件,據我的經驗好像都沒辦法利用「JsonConvert」套件序列化成功。如果是EF物件的話可能就要先轉換為DTO或者是ViewModel之類的模型才能成功轉換。
所以同理,我認為我們也一樣要先將「IPagedList」轉換為一個比較單純的類別模型,等成功轉換為「Json String」傳回前台端後,我們再將其轉換回「IPagedList」,那仔細去看「IPagedList」的結構,大致分為兩個屬性如下(圖一),Items會放列表資訊的List,而MetaData則是存資料大小,分頁大小,當前頁碼等資訊。
(圖一)
所以API端要序列化回傳的Model架構大致上就如下(圖二)
(圖二)
那麼關於Items的取得,我們就直接將當前的「IPagedList物件」ToList即可取得;而MetaData,仔細看PagedListMetadata的內容,可以發現將「IPagedList物件」放入PagedListMetadata的建構子裡頭即可取得整個PagedListMetadata 物件 ,如下(圖三)。
(圖三)
好的,現在我們可以將「IPagedList物件」給序列化了,由於「PagedListMetadata」無法直接序列化,因此我們必須自訂一個,「PaginationMetaData」來替代「PagedListMetadata」。
*類別
public class PaginationMetaData { public int FirstItemOnPage { get; set; } public bool HasNextPage { get; set; } public bool HasPreviousPage { get; set; } public bool IsFirstPage { get; set; } public bool IsLastPage { get; set; } public int LastItemOnPage { get; set; } public int PageCount { get; set; } public int PageNumber { get; set; } public int PageSize { get; set; } public int TotalItemCount { get; set; } } public class PaginationEntityClass<T> { public PaginationEntityClass() { Items = new List<T>(); } public IEnumerable<T> Items { get; set; } public PaginationMetaData MetaData { get; set; } }
*擴充方法
public static string IPagedListToJsonString<T>(this IPagedList<T> pagedlist) { var items = pagedlist.ToList(); var metadataString = new PagedListMetadata(pagedlist).ToJsonString(); var metaData = metadataString.DeserializeObject<PaginationMetaData>(); var pagedWithMetaData = new PaginationEntityClass<T> { Items = items, MetaData = metaData }; return pagedWithMetaData.ToJsonString(); } public static string ToJsonString<T>(this T data) { if (data == null) { return string.Empty; } return JsonConvert.SerializeObject(data); } public static T DeserializeObject<T>(this string json) { if (string.IsNullOrWhiteSpace(json)) { return default; } return JsonConvert.DeserializeObject<T>(json); }
(二)反序列化「PaginationEntityClass」 Json String
我們先將「PaginationEntityClass」 Json String反序列化為「PaginationEntityClass」,再利用「PaginationEntityClass」組成一個「StaticPagedList」,因為「StaticPagedList」有繼承「IPagedList」,所以我們直接回傳新組成的「StaticPagedList」物件即可。
*擴充方法
public static IPagedList<T> JsonToIPagedList<T>(this string josn) { try { var result = josn.DeserializeObject<PaginationEntityClass<T>>(); var pagelist = new StaticPagedList<T>( result.Items, result.MetaData.PageNumber, result.MetaData.PageSize, result.MetaData.TotalItemCount); return pagelist; } catch(Exception e) { e.ExceptionLogRun(); return default; } } public static string ToJsonString<T>(this T data) { if (data == null) { return string.Empty; } return JsonConvert.SerializeObject(data); } public static T DeserializeObject<T>(this string json) { if (string.IsNullOrWhiteSpace(json)) { return default; } return JsonConvert.DeserializeObject<T>(json); }
留言
張貼留言