Javascript 在 WCF 服务方法中使用 JSON
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5497412/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Consuming JSON in WCF service method
提问by Simon Rigby
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.
在一个更大的项目中,我无法使用 WCF 服务方法来使用 JSON 参数。所以我制作了一个较小的测试用例,并且行为得到了回应。如果我调试服务,我可以在服务调用时看到参数值为空。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 消息是“期望状态 'Element'.. 遇到名称为 ''、命名空间为 '' 的 'Text'。'。
I have tried sending an unwrapped version of the JSON ...
我曾尝试发送 JSON 的解包版本...
{"Name":"Simon","Score":"100","Club":"Rigby"}
{"Name":"Simon","Score":"100","Club":"Rigby"}
but at the service the parameter is null, and no formatter exceptions.
但在服务中,该参数为空,并且没有格式化程序异常。
This is the system.serviceModel branch of the service web.config:
这是服务 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>
And here is the Player DataContract.
这是 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.
非常感谢。
回答by Oleg
You encode the input parameter player
of the method TotalScore
in the wrong way.
您以错误的方式player
对方法的输入参数进行编码TotalScore
。
I recommend you to use JSON.stringify
function from json2.jsto convert any JavaScript objects to JSON.
我建议您使用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");
}
});
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.Wrapped
将TotalScore
方法的属性BodyStyle = WebMessageBodyStyle.WrappedRequest
更改为alert(data.TotalScoreResult)
,则可以将success
句柄中的更改为alert(data)
。
回答by Shiraz Bhaiji
You have not sepcified the Method parameter on web invoke. See: http://msdn.microsoft.com/en-us/library/bb472541(v=vs.90).aspx
您尚未在 Web 调用上指定 Method 参数。请参阅:http: //msdn.microsoft.com/en-us/library/bb472541(v=vs.90).aspx
回答by nvtthang
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-rest-service-from-jquery-causes-405-method-not-allowed/
Hope this help!
希望这有帮助!