In a larger project I am having trouble getting a WCF service method to consume a JSON parameter. So I produced a smaller test case and the behaviour is echoed. If I debug the service I can see the parameter value is null at the service call. Fiddler confirms that the JSON is being sent and JsonLint confirms it is valid.
在一个较大的项目中,我在使用JSON参数的WCF服务方法时遇到了麻烦。因此,我制作了一个较小的测试用例,并且这种行为得到了响应。如果我调试服务,我可以在服务调用中看到参数值为null。Fiddler确认正在发送JSON, JsonLint确认它是有效的。
Code below with annotations from debugging.
下面的代码带有来自调试的注释。
[ServiceContract]
public interface IWCFService
{
[OperationContract]
[WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "getstring")]
string GetString();
[OperationContract]
[WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "getplayer")]
//[WebGet(BodyStyle = WebMessageBodyStyle.WrappedRequest,
// ResponseFormat = WebMessageFormat.Json,
// UriTemplate = "getplayers")]
Player GetPlayer();
[OperationContract]
[WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "getplayers")]
List<Player> GetPlayers();
[OperationContract]
[WebInvoke(
Method = "POST",
BodyStyle = WebMessageBodyStyle.Wrapped,
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json,
UriTemplate = "totalscore")]
string TotalScore(Player player);
}
... and its implementation
…及其实现
public class WCFService : IWCFService
{
public string GetString()
{
return "hello from GetString";
}
public Player GetPlayer()
{
return new Player()
{
Name = "Simon",
Score = 1000,
Club = new Club()
{
Name = "Tigers",
Town = "Glenelg"
}
};
}
public List<Player> GetPlayers()
{
return new List<Player>()
{
new Player()
{
Name = "Simon",
Score = 1000 ,
Club=new Club()
{
Name="Tigers",
Town = "Glenelg"
}
},
new Player()
{
Name = "Fred", Score = 50,
Club=new Club()
{
Name="Blues",
Town="Sturt"
}
}
};
}
public string TotalScore(Player player)
{
return player.Score.ToString();
}
}
Calling any of the first three methods works correctly (but no parameters as you'll note). Calling the last method (TotalScore) with this client code ...
调用前三个方法中的任何一个都可以正常工作(但是您将注意到没有参数)。使用此客户端代码调用最后一个方法(TotalScore)…
function SendPlayerForTotal() {
var json = '{ "player":{"Name":"' + $("#Name").val() + '"'
+ ',"Score":"' + $("#Score").val() + '"'
+ ',"Club":"' + $("#Club").val() + '"}}';
$.ajax(
{
type: "POST",
contentType: "application/json; charset=utf-8",
url: "http://localhost/wcfservice/wcfservice.svc/json/TotalScore",
data: json,
dataType: "json",
success: function (data) { alert(data); },
error: function () { alert("Not Done"); }
});
}
... results in ...
…导致……
There was an error while trying to deserialize parameter http://tempuri.org/:player. The InnerException message was 'Expecting state 'Element'.. Encountered 'Text' with name '', namespace ''. '.
在尝试反序列化参数http://tempuri.org/:player时发生了错误。InnerException消息是“预期状态”元素。遇到“Text”和“name”、“namespace”。”。
I have tried sending an unwrapped version of the JSON ...
我尝试过发送一个未包装的JSON版本…
{"Name":"Simon","Score":"100","Club":"Rigby"}
{ " Name ":“西蒙”、“分数”:“100”,“俱乐部”:“Rigby”}
but at the service the parameter is null, and no formatter exceptions.
但在服务中,参数为null,没有格式化程序异常。
This is the system.serviceModel branch of the service web.config:
这是系统。service web的serviceModel分支。config:
<system.serviceModel>
<services>
<service name="WCFService.WCFService" behaviorConfiguration="WCFService.DefaultBehavior">
<endpoint address="json" binding="webHttpBinding" contract="WCFService.IWCFService" behaviorConfiguration="jsonBehavior"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WCFService.DefaultBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="jsonBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
And here is the Player DataContract.
这是玩家数据记录。
[DataContract(Name = "Player")]
public class Player
{
private string _name;
private int _score;
private Club _club;
[DataMember]
public string Name { get { return _name; } set { _name = value; } }
[DataMember]
public int Score { get { return _score; } set { _score = value; } }
[DataMember]
public Club Club { get { return _club; } set { _club = value; } }
}
Any help greatly appreciated and if any other info is required, please let me know.
非常感谢您的帮助,如果需要其他信息,请告诉我。
Many thanks.
多谢。
3 个解决方案
#1
10
You encode the input parameter player
of the method TotalScore
in the wrong way.
您以错误的方式对方法TotalScore的输入参数播放器进行编码。
I recommend you to use JSON.stringify
function from json2.js to convert any JavaScript objects to JSON.
我建议您使用JSON。从json2 stringify函数。将任何JavaScript对象转换为JSON。
var myPlayer = {
Name: "Simon",
Score: 1000,
Club: {
Name: "Tigers",
Town: "Glenelg"
}
};
$.ajax({
type: "POST",
url: "/wcfservice/wcfservice.svc/json/TotalScore",
data: JSON.stringify({player:myPlayer}), // for BodyStyle equal to
// WebMessageBodyStyle.Wrapped or
// WebMessageBodyStyle.WrappedRequest
// data: JSON.stringify(myPlayer), // for no BodyStyle attribute
// or WebMessageBodyStyle.WrappedResponse
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data, textStatus, xhr) {
alert(data.TotalScoreResult); // for BodyStyle = WebMessageBodyStyle.Wrapped
// or WebMessageBodyStyle.WrappedResponse
// alert(data); // for BodyStyle = WebMessageBodyStyle.WrappedRequest
// or for no BodyStyle attributes
},
error: function (xhr, textStatus, ex) {
alert("Not Done");
}
});
If you change the BodyStyle = WebMessageBodyStyle.Wrapped
attribute of the TotalScore
method to BodyStyle = WebMessageBodyStyle.WrappedRequest
you can change the alert(data.TotalScoreResult)
in the success
handle to alert(data)
.
如果你改变了BodyStyle = WebMessageBodyStyle。TotalScore方法的包装属性为BodyStyle = WebMessageBodyStyle。WrappedRequest命令可以在成功句柄中更改alert(data. totalscoreresult)以警告(data)。
#2
0
You have not sepcified the Method parameter on web invoke. See: http://msdn.microsoft.com/en-us/library/bb472541(v=vs.90).aspx
您还没有对web调用的方法参数进行验证。参见:http://msdn.microsoft.com/en-us/library/bb472541(v =应用程序). aspx
#3
0
I got the same problems (405 methods not allowed) using WCF POST JSON data. I found on this article below
我使用WCF POST JSON数据得到了相同的问题(不允许使用405种方法)。我在下面这篇文章中找到的
http://blog.weareon.net/calling-wcf-rest-service-from-jquery-causes-405-method-not-allowed/
http://blog.weareon.net/calling - wcf -休息-服务-从jquery -原因- 405——不——allowed/方法
Hope this help!
希望这次的帮助!
#1
10
You encode the input parameter player
of the method TotalScore
in the wrong way.
您以错误的方式对方法TotalScore的输入参数播放器进行编码。
I recommend you to use JSON.stringify
function from json2.js to convert any JavaScript objects to JSON.
我建议您使用JSON。从json2 stringify函数。将任何JavaScript对象转换为JSON。
var myPlayer = {
Name: "Simon",
Score: 1000,
Club: {
Name: "Tigers",
Town: "Glenelg"
}
};
$.ajax({
type: "POST",
url: "/wcfservice/wcfservice.svc/json/TotalScore",
data: JSON.stringify({player:myPlayer}), // for BodyStyle equal to
// WebMessageBodyStyle.Wrapped or
// WebMessageBodyStyle.WrappedRequest
// data: JSON.stringify(myPlayer), // for no BodyStyle attribute
// or WebMessageBodyStyle.WrappedResponse
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data, textStatus, xhr) {
alert(data.TotalScoreResult); // for BodyStyle = WebMessageBodyStyle.Wrapped
// or WebMessageBodyStyle.WrappedResponse
// alert(data); // for BodyStyle = WebMessageBodyStyle.WrappedRequest
// or for no BodyStyle attributes
},
error: function (xhr, textStatus, ex) {
alert("Not Done");
}
});
If you change the BodyStyle = WebMessageBodyStyle.Wrapped
attribute of the TotalScore
method to BodyStyle = WebMessageBodyStyle.WrappedRequest
you can change the alert(data.TotalScoreResult)
in the success
handle to alert(data)
.
如果你改变了BodyStyle = WebMessageBodyStyle。TotalScore方法的包装属性为BodyStyle = WebMessageBodyStyle。WrappedRequest命令可以在成功句柄中更改alert(data. totalscoreresult)以警告(data)。
#2
0
You have not sepcified the Method parameter on web invoke. See: http://msdn.microsoft.com/en-us/library/bb472541(v=vs.90).aspx
您还没有对web调用的方法参数进行验证。参见:http://msdn.microsoft.com/en-us/library/bb472541(v =应用程序). aspx
#3
0
I got the same problems (405 methods not allowed) using WCF POST JSON data. I found on this article below
我使用WCF POST JSON数据得到了相同的问题(不允许使用405种方法)。我在下面这篇文章中找到的
http://blog.weareon.net/calling-wcf-rest-service-from-jquery-causes-405-method-not-allowed/
http://blog.weareon.net/calling - wcf -休息-服务-从jquery -原因- 405——不——allowed/方法
Hope this help!
希望这次的帮助!