长时间的lurcher,第一次海报在这里。 我一直在努力解决这个问题几天了,并会感谢任何提示。 我在下面讨论这个问题。WCF RESTful Web服务与JSON.Net:避免双重序列化
我想要实现:
我想成立一个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对象和感觉真的对我自己很好。
经过一些Google搜索后,我发现一些帖子提示在.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响应汤头发的结果是字典对象的JSON响应“有效载荷”被映射的出路。它是一个对象数组,而我期待的是一个JSON对象没有这个“Key”,“Value”业务。不是我想要的。关闭,但很挑剔在客户端处理。没有人喜欢膨胀和不必要的工作,所以大拇指向下。
做一些更多的解决方案我读了一些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序列化器,或者其他一些解决方案?
指针非常感谢。
太棒了!感谢Regfor。是的,我从头开始创建这项服务,并有自由选择它的实施方式。我开始看看你提供的链接,他们看起来似乎比我想的要简单得多。我没有时间阅读和遵循教程,但很快就会把我之前发布的代码放在“我从中学到了东西,但改变了方向”的篮子。谢谢! – coderigo 2012-07-22 06:34:36