在较大的项目中,我无法获取WCF服务方法来使用JSON参数。所以我制作了一个较小的测试用例,并且行为得到了回应。如果我调试服务,我可以看到服务调用时参数值为null。 Fiddler确认正在发送JSON,JsonLint确认它是有效的。
下面的代码,带有调试注释。
[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);
}
......及其实施
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();
}
}
调用前三种方法中的任何一种都能正常工作(但没有参数,你会注意到)。使用此客户端代码调用最后一个方法(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"); }
});
}
......导致......
尝试反序列化参数http://tempuri.org/:player时出错。 InnerException消息是'Expecting state'Element'..遇到名为'',namespace''的'Text'。 ”。
我试过发送一个未包装的JSON版本......
{ “名称”: “西蒙”, “得分”: “100”, “俱乐部”: “格比”}
但是在服务中,参数为null,没有格式化程序异常。
这是服务web.config的system.serviceModel分支:
<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>
这是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; } }
}
任何帮助都非常感谢,如果需要任何其他信息,请告诉我。
非常感谢。
答案 0 :(得分:10)
您以错误的方式对方法player
的输入参数TotalScore
进行编码。
我建议您使用json2.js中的JSON.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");
}
});
如果您将BodyStyle = WebMessageBodyStyle.Wrapped
方法的TotalScore
属性更改为BodyStyle = WebMessageBodyStyle.WrappedRequest
,则可以将alert(data.TotalScoreResult)
句柄中的success
更改为alert(data)
答案 1 :(得分:0)
您尚未在Web调用中指定Method参数。请参阅:http://msdn.microsoft.com/en-us/library/bb472541(v=vs.90).aspx
答案 2 :(得分:0)
我使用WCF POST JSON数据遇到了同样的问题(不允许使用405种方法)。我在下面的这篇文章中找到了
http://blog.weareon.net/calling-wcf-rest-service-from-jquery-causes-405-method-not-allowed/
希望这有帮助!