[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);
}
留言
張貼留言