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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 17:28:05  来源:igfitidea点击:

Consuming JSON in WCF service method

javascriptjquerywcfjsonnullreferenceexception

提问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 playerof the method TotalScorein the wrong way.

您以错误的方式player对方法的输入参数进行编码TotalScore

I recommend you to use JSON.stringifyfunction 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.Wrappedattribute of the TotalScoremethod to BodyStyle = WebMessageBodyStyle.WrappedRequestyou can change the alert(data.TotalScoreResult)in the successhandle to alert(data).

如果BodyStyle = WebMessageBodyStyle.WrappedTotalScore方法的属性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!

希望这有帮助!