gpt4 book ai didi

json - 带有JSON.Net的WCF RESTful Web服务:避免双重序列化

转载 作者:行者123 更新时间:2023-12-05 00:33:48 25 4
gpt4 key购买 nike

很久很久以前,这里是第一次海报。
我已经为这个问题努力了几天,请多多指教。
我在下面将问题分解。

我想要达到的目标:
我想设置一个JSON WCF Web服务,但是我想使用JSON.net序列化器而不是WCF附带的序列化器。为什么?因为我发现使用WCF附带的序列化序列会使集合变大(我将在下面显示我的意思的示例)。该服务的最终用户将是一个JavaScript客户端,因此我不想让客户端做更多的事情来浏览JSON。

我提出了一个简单的示例,说明了我想要的东西,并着手尝试使其在C#中工作。我必须承认,很长一段时间都没有使用过.NET,这可能会导致我的速度变慢。无论如何,我都有耐心等待库存。

因此,我想要一个接受用户名并返回带有用户信息的JSON对象的服务。
我设想将该服务称为以下名称:

http://someHostName/whoareyou?username=paul


并让服务对此做出响应:

{
"errorCode": 0,
"payLoad" : {
"userFullName": "Paul The Octopus",
"userLevel" : "Administrator"
}
}


我可以在JavaScript或PHP中轻松使用上述响应的JSON对象,并对自己感觉很好。

经过一番谷歌搜索后,我发现一些帖子暗示使用.NET Framework 4中的WCF可以很容易地完成。我在一段时间前对WCF做了一些摆弄,但是早已忘记了它的99%,所以我发现并遵循这篇文章适应我的目标:
http://www.codeproject.com/Articles/105273/Create-RESTful-WCF-Service-API-Step-By-Step-Guide#

尝试1:
在上面的文章之后,我能够设置一个WCF服务(下面列出的代码),该服务可以实现我想要的功能,但是生成的JSON输出有点肿,如下所示。

RestServiceImpl.svc.cs文件

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using Newtonsoft.Json;
using System.Collections.Specialized;
//Based on this psot: http://www.codeproject.com/Articles/105273/Create-RESTful-WCF-Service-API-Step-By-Step-Guide

namespace RestService
{
public class RestServiceImpl : IRestServiceImpl
{
#region IRestService Members

public WhoAreYouResponse whoareyou(string username)
{
var payLoad = new Dictionary<string, string>
{
{"userFullName", "Paul The Octopus"},
{"userLevel", "Administrator"}
};

WhoAreYouResponse whoAreYouResponse = new WhoAreYouResponse
{
errorCode = 0,
payLoad = payLoad
};

return whoAreYouResponse;
}

#endregion
}

//Helper bits to be used in service implementation
public class WhoAreYouResponse
{
public int errorCode { get; set; }
public Dictionary<string,string> payLoad { get; set; }
}
}


IRestServiceImpl.cs文件

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace RestService
{
[ServiceContract]
public interface IRestServiceImpl
{
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "json/whoareyou?username={username}")]
WhoAreYouResponse whoareyou(string username);
}
}


Web.config文件

<?xml version="1.0"?>
<configuration>

<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="RestService.RestServiceImpl" behaviorConfiguration="ServiceBehavior">
<endpoint address="" binding="webHttpBinding" contract="RestService.IRestServiceImpl" behaviorConfiguration="web">
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>

</configuration>


*通过这样的浏览器 http://192.168.0.84/TestRestService/RestServiceImpl.svc/json/whoareyou?username=paul*调用服务的结果

{
"errorCode":0,
"payLoad" : [
{"Key":"userFullName", "Value":"Paul The Octopus"},
{"Key":"userLevel","Value":"Administrator"}
]
}


JSON响应中汤中的头发是将Dictionary对象在JSON响应中映射到“ payLoad”的方式。它是一个对象数组,而我期望JSON对象解决此“键”,“值”业务。不完全是我想要的。封闭,但在客户端处理时有点挑剔。没有人喜欢膨胀和不必要的工作,所以请对此表示反对。

做一些更多的解决方案,我读了一些SO帖子,暗示这里发生的事情是该服务正在使用内置的序列化程序
并且不会序列化“字典以任何其他方式”。要获得我期望的格式,需要做一些额外的工作。
所以,我想,使用另一个串行器怎么样?
遵循这个想法,我在这里发现了这个坏男孩: http://james.newtonking.com/projects/json-net.aspx

这导致我在下面进行第二次尝试。

尝试2:
将JSON.NET序列化程序下载并导入到我的小项目中,我更改了以下文件,使其看起来像这样(将whoareyou方法的返回类型更改为字符串):

RestServiceImpl.svc.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using Newtonsoft.Json;
using System.Collections.Specialized;
//Based on this psot: http://www.codeproject.com/Articles/105273/Create-RESTful-WCF-Service-API-Step-By-Step-Guide

namespace RestService
{
public class RestServiceImpl : IRestServiceImpl
{
#region IRestService Members

public string whoareyou(string username)
{
var payLoad = new Dictionary<string, string>
{
{"userFullName", "Paul The Octopus"},
{"userLevel", "Administrator"}
};

WhoAreYouResponse whoAreYouResponse = new WhoAreYouResponse
{
errorCode = 0,
payLoad = payLoad
};

return JsonConvert.SerializeObject(whoAreYouResponse);
}

#endregion
}

//Helper bits to be used in service implementation
public class WhoAreYouResponse
{
public int errorCode { get; set; }
public Dictionary<string,string> payLoad { get; set; }
}
}


IRestServiceImpl.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace RestService
{
[ServiceContract]
public interface IRestServiceImpl
{
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "json/whoareyou?username={username}")]
string whoareyou(string username);
}
}


当调用该服务时,我得到以下响应:

"{
\"errorCode\":0,
\"payLoad\":{
\"userFullName\":\"Paul The Octopus\",
\"userLevel\":\"Administrator\"}
}"


优胜者!那就是我想要和期望的……但是。倒退卡车。整个JSON对象用双引号引起来!
嗯这是一个包含JSON对象的字符串。我从汤中取出头发,现在有一只苍蝇飞了进去!

经过一会儿的抓挠,很明显(我认为)正在发生的事情是JSON.NET序列化器的运行就像一个符咒,将JSON对象分散在一个字符串中,然后将其放入WCF序列化器中,并从本质上进行了字符串化。所以我在返回中看到的是一个JSON字符串。很近!实际上,我的方法whoareyou说它返回一个字符串,这几乎是我的错。

因此,我的问题是,如何让这个有问题的孩子停止这项双重序列化业务?我找不到我的whoareyou方法的返回类型,就像JSON对象一样。
有没有一种方法告诉WCF使用JSON.NET序列化器,或者某种解决方案?

指针非常感谢。

最佳答案

据我了解,您是从头开始创建服务,并且对实现REST服务的方式没有任何限制。然后,我建议您使用ASP.NET WebApi

http://www.asp.net/web-api

不要使用传统的Web服务技术,因为在较新的版本中,已经为您完成了许多样板代码。

使用Web API,您可以轻松替换或添加任何序列化器/格式器。以下文章介绍了如何执行此操作:

http://www.asp.net/web-api/overview/formats-and-model-binding/media-formatters

http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization

我遇到了序列化的问题,您已经描述了这种方法并解决了这些问题。根据我在较早的Web服务技术(WCF 3.5 Rest Starter Kit,
Wcf 4 REST)可以用更困难的方式完成。

关于json - 带有JSON.Net的WCF RESTful Web服务:避免双重序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11572203/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com