[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);
  }

留言

這個網誌中的熱門文章

[Visual Studio]位於網際網路或是限制區域上 或是檔案上標有 web 字樣 所以無法處理該檔案。若希望處理這些檔案 請移除 web 字樣。

[IIS] IIS執行時,發生拒絕存取路徑 問題

[windows] xcopy 備份至 「網路磁碟機」