使用 JSON 对 WCF 服务进行分页

Posted

技术标签:

【中文标题】使用 JSON 对 WCF 服务进行分页【英文标题】:Pagination on WCF Service with JSON 【发布时间】:2018-11-29 07:17:25 【问题描述】:

我已经创建了一个向某个客户端发送 JSON 字符串的 WCF 服务。我被要求进行某种分页,这样它就不会一次发送所有数据,但我不确定如何最好地进行此操作。到目前为止,我在网上阅读的内容要么非常模糊,要么并不真正适用于我的特定应用程序,至少在我理解的方式上不适用。

这是我的 WCF 的工作原理:

得到一个 IService1:

        [OperationContract()]
    [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Json, UriTemplate = "/BP?vCaseNr=vCaseNr")]
    Stream BoligPraesentation(string vCaseNr);

服务1:

public Stream BoligPraesentation(string vSagsNr)

 SqlConnection con = new SqlConnection();
 con = Database();

 SqlDataAdapter dau = new SqlDataAdapter(*long sql here*, con);

 DataTable dtu = new DataTable();
 dau.Fill(dtu);
 string json = GetJson(dtu)

            if (json != "[]")
            
                json = json.Replace("[", "");
                json = json.Replace("]", "");
                json = "\"Things\": [" + json + "]";
            

 WebOperationContext.Current.OutgoingResponse.ContentType = 
 "application/json; charset=utf-8";
 return new MemoryStream(Encoding.UTF8.GetBytes(json));

GetJSon 看起来像这样:

private string GetJson(DataTable dt)
    
        System.Web.Script.Serialization.javascriptSerializer Jserializer = new System.Web.Script.Serialization.JavaScriptSerializer();
        List<Dictionary<string, object>> rowsList = new List<Dictionary<string, object>>();
        Dictionary<string, object> row = null;

        foreach (DataRow dr in dt.Rows)
        
            row = new Dictionary<string, object>();
            foreach (DataColumn col in dt.Columns)
            
                row.Add(col.ColumnName, dr[col]);
            

            rowsList.Add(row);
        

        return Jserializer.Serialize(rowsList);
    

返回后的 JSON 看起来有点像这样:

"Things": ["CaseNr":6,"Titel":"some place V","Areal":null,"Adresse1":"Hsome address","Rum":2,"Etage":0,"PostNr":"9999","ByNavn":"city","EjendomNavn":"name here","Status":"LEDIG","Leje":"343434","AntalBilleder":0,"AntalProspekter":0,"AntalKort":0,"AntalTegninger":0,"CaseNr":4,"Titel":"big place","Areal":null,"Adresse1":"adress 555","Rum":null,"Etage":3,"PostNr":"2222","ByNavn":"Germacity","EjendomNavn":"HSbuilding ApS","Status":"OPTAGET","Leje":"0.00","AntalBilleder":0,"AntalProspekter":0,"AntalKort":0,"AntalTegninger":0

我想一次发送 20 个,或者让客户决定多少个,而不是同时发送所有东西(可能比我展示的两个多)。不过,我完全不确定如何进行这项工作,有什么建议吗?

PS:如果我需要显示更多信息,请说出来。

【问题讨论】:

【参考方案1】:

以下是分页需要遵循的通用步骤。

    在客户端发出的请求中获取pageNumberpageSize(表示单个页面中的对象数,在您的情况下为20)。 在您的*long sql* 中使用这些数字过滤掉结果,从而得到page。使用 LINQ 的示例如下所示:var requestedPage = dbEntities.Skip(pageNumber*pageSize).Take(pageSize) 将此类页面转换为JSON 或您需要的格式(流?)并返回。

pageNumberpageSizetotal(表中所有实体的数量)连同page 一起发回也是一个好主意。这将只是为客户端请求nextpreviousany page 的逻辑。

这里是我上面提到的 LINQ and pagination

的更多变体

【讨论】:

【参考方案2】:

谢谢你,我现在知道了。

基本上我有两个 SQL 查询。像这样获取元数据的一种:

declare @pageindex int select @pageindex = 2
declare @pagerows int select @pagerows = 10

select count(distinct u.Id) as NumberofRows, @pagerows as PageRows, @pageindex as PageIndex 
from SomeTable u
inner join ...
where ...

还有我的大家伙:

declare @pageindex int select @pageindex = 2
declare @pagerows int select @pagerows = 10

select * from(select ROW_NUMBER() over(order by u.Id) Row, *other selects*
inner join...
where...
) a where Row between(@pageRows* @pageindex) -@pageRows + 1 and(@pageRows * @pageindex)

然后我就像这样将两个 json 添加在一起:

                json = "\"Meta\":" + GetJson(dtrows);
                json = json.Replace("[", "");
                json = json.Replace("]", "");

                json += ", \"Things\":" + GetJson(dtu) + "";

【讨论】:

以上是关于使用 JSON 对 WCF 服务进行分页的主要内容,如果未能解决你的问题,请参考以下文章

如何对 WCF 4 RESTful 服务进行身份验证?

2003 年使用 POST / JSON 托管 WCF Rest 服务

jQuery - 使用 ajax 调用将 JSON 发送到 WCF 服务为空

将 JSON 发送到 C# WCF 服务会导致:请求实体太大

在 WCF 中使用分页

使用 transportCredentialOnly 安全性对 RESTful WCF 服务的跨域 Ajax JSON POST 支持