问题调用WCF服务库从jQuery的 [英] Problem Calling WCF Service Library from jQuery

查看:124
本文介绍了问题调用WCF服务库从jQuery的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个WCF服务库通过我的ASPX的网站暴露如下:

I have a WCF Service Library exposed through my ASPX site as follows

[System.ServiceModel.OperationContract]
[System.ServiceModel.Web.WebInvoke(
Method= "POST",
RequestFormat=System.ServiceModel.Web. WebMessageFormat .Json,
ResponseFormat=System.ServiceModel.Web.WebMessageFormat .Json)]
LogonResponse Logon(LogonRequest logonRequest);


[System.Runtime.Serialization.DataContract]
[ Serializable()]
public class LogonRequest
{
[System.Runtime.Serialization.DataMember]
public string EMailAddress;
[System.Runtime.Serialization.DataMember]
public string Password;
}

在我的测试页,我可以打电话或者通过MS阿贾克斯: -

In My test page I can call either through MS Ajax : -

<asp:ScriptManager ID ="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="~/testService.svc" />
</Services>
</asp:ScriptManager>
.
.
.
function clsLogonRequest(eMailAddress, password) {
this .EMailAddress = eMailAddress;
this .Password = password;
}

function login(eMailAddress, password) {
var LogonRequest = new clsLogonRequest(eMailAddress, password);
name.API.IAPI.Logon(LogonRequest, onSuccess, onFailure);
}

function onSuccess(result) {
$( "#txtSessionId").val(result.SessionId);
$( "#txtUserName").val(result.Name);
$( "#txtUserId").val(result.UserId);
}

这工作得很好,或者通过一个jQuery $。阿贾克斯电话: -

which works fine, or through a jQuery $.ajax call: -

$(document).ready(function() {
$( "#Button1").click(function() {
var LogonRequest = new clsLogonRequest( '*************' , '***********');
$.ajax({
type: "POST",
url: "testService.svc/Logon",
data: "{'logonRequest':" + JSON.stringify(LogonRequest) + "}" ,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
alert(msg.d);
}
});
});
});

不 - 萤火下我可以看到500内部服务器错误消息和异常启动

Which does not - under FireBug I can see the 500 Internal Server Error message and the exception starts

{"ExceptionDetail":{"HelpLink":null,"InnerException":null,"Message":"The token '\"' was expected but found '''.","StackTrace":"   at System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, String res, String arg1, String arg2, String arg3)\u000d\u000a   at System.Xml.XmlExceptionHelper .ThrowTokenExpected(XmlDictionaryReader reader, String expected, Char found)\u000d\u000a   at System.Runtime...

为什么它似乎jQuery的通话路过时,我明确告诉它的XML不是(我怎么能阻止它这样呼吁所有来源的处理尽可能自然)?

Why does it appear that the jQuery call is passing XML when I'm specifically telling it not to (and how can I stop it so that calls from all sources are handled as naturally as possible)?

在此先感谢。

编辑:

感谢您的建议,我看你说的话,认为我这个问题的解释是不够清晰。

Thanks for the suggestions, I've looked at what you said and think that my explanation of the problem was not clear enough.

现在的问题是不是JSON不被发送,它被发送,并以正确的格式,我可以看到,从萤火虫。的问题是,在WCF服务库似乎被期待XML和下降,当它接收JSON过度

The problem is not that JSON is not being sent, it is being sent and is in the correct format, I can see that from firebug. The problem is that the WCF Service Library appears to be expecting XML and falls over when it receives JSON.

只是为了确保我没有忽略建议的解决方案,这里是web.config中提取物 - 我试图从行为删除和删除服务/服务/端点标签behaviorConfiguration属性,而只是使没有得到了页面的整个事情失败。

Just to be sure I haven't overlooked the suggested solution, here is the web.Config extract - I've tried removing from the behaviour and removing the behaviorConfiguration attribute from the services/service/endpoint tag and that just makes the whole thing fail without getting out of the page.

<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name ="MyServiceTypeBehaviors ">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name ="AspNetAjaxBehavior">
<enableWebScript/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled= "true " />
<services>
<service name ="test.API.API" behaviorConfiguration = " MyServiceTypeBehaviors">
<endpoint behaviorConfiguration="AspNetAjaxBehavior" binding = " webHttpBinding" contract="test.API.IAPI" />
<endpoint contract ="IMetadataExchange" binding= " mexHttpBinding" address="mex" />
</service>
</services>
</system.serviceModel>

在此先感谢

推荐答案

我猜你已经应用了WebScriptEnablingBehavior(中的.config enableWebScript元)?这将导致被包裹在一个JSON对象名称为D单场,然后包含一个对象,你命名参数的所有请求。所以,你需要改变jQuery的数据是:

I'm guessing you have applied the WebScriptEnablingBehavior (enableWebScript element in .config)? This causes all requests to be wrapped in a JSON object with a single field named "d" which then contains an object with your named parameters. So you would need to change the jQuery data to be:

data: "{d:{logonRequest:" + JSON.stringify(LogonRequest) + "}}"

无论是或删除enableWebScript行为,但是,如果你这样做,你必须应用webHttp行为来代替。现在,不幸的是,默认的编码是那么XML和行为不提供任何开关来控制编码的整个服务(糟糕的设计由MSFT)。所以,要么你要嫁给自己一个sepcific编码每个方法,通过设置请求/ ResponseFormat属性,或者,我怎么过去这样处理,是我创建了一个EnhancedWebHttpElement适用相同的WebHttpBehavior,但给人的配置水平控制它的各种性能。采用这种结构的好处是,你现在可以通过公开使用ASP.NET AJAX编码不同端点的同一WCF服务于一体,简单的JSON另一方面,甚至POX在另一个之上。

Either that or remove the enableWebScript behavior, but, if you do that, you must apply the webHttp behavior instead. Now, unfortunately, the default encoding is then XML and the behavior does not offer any switches to control the encoding for an entire service (bad design by MSFT). So, either you must marry yourself to a sepcific encoding on each method by setting the Request/ResponseFormat properties, or, how I've handled this in the past, is that I've created an "EnhancedWebHttpElement" which applies the same WebHttpBehavior, but gives config level control over it's various properties. The benefit of using this configuration is that you can now expose your same WCF service via different endpoints using ASP.NET AJAX encoding on one, plain JSON on the other and maybe even POX on another.

这里的code:

public sealed class EnhancedWebHttpElement : BehaviorExtensionElement
{
    #region Type specific properties

    [ConfigurationProperty("defaultBodyStyle", DefaultValue=WebMessageBodyStyle.Bare)]
    public WebMessageBodyStyle DefaultBodyStyle
    {
        get
        {
            return (WebMessageBodyStyle)this["defaultBodyStyle"];
        }

        set
        {
            this["defaultBodyStyle"] = value;
        }
    }

    [ConfigurationProperty("defaultOutgoingRequestFormat", DefaultValue=WebMessageFormat.Xml)]
    public WebMessageFormat DefaultOutgoingRequestFormat
    {
        get
        {
            return (WebMessageFormat)this["defaultOutgoingRequestFormat"];
        }

        set
        {
            this["defaultOutgoingRequestFormat"] = value;
        }
    }

    [ConfigurationProperty("defaultOutgoingResponseFormat", DefaultValue=WebMessageFormat.Xml)]
    public WebMessageFormat DefaultOutgoingResponseFormat
    {
        get
        {
            return (WebMessageFormat)this["defaultOutgoingResponseFormat"];
        }

        set
        {
            this["defaultOutgoingResponseFormat"] = value;
        }
    }       

    #endregion

    #region Base class overrides

    protected override object CreateBehavior()
    {
        WebHttpBehavior result = new WebHttpBehavior();

        result.DefaultBodyStyle = this.DefaultBodyStyle;
        result.DefaultOutgoingRequestFormat = this.DefaultOutgoingRequestFormat;
        result.DefaultOutgoingResponseFormat = this.DefaultOutgoingResponseFormat;

        return result;
    }

    public override Type BehaviorType
    {
        get
        {
            return typeof(WebHttpBehavior);
        }
    }

    #endregion
}

然后你必须注册:

And then you have to register it:

<system.serviceModel>
    <extensions>
        <behaviorExtensions>
            <add name="enhancedWebHttp" type="MyNamespace.EnhancedWebHttpElement, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
            </behaviorExtensions>
    </extensions>

然后你使用它,如下所示:

And then you use it like so:

<behavior name="MyBehavior">
    <enhancedWebHttp defaultOutgoingRequestFormat="JSON" defaultOutgoingResponseFormat="JSON" />
</behavior>


更新:


UPDATE:

这答案以上适用严格.NET 3.x的如果你使用.NET 4.x版,那么你现在可以使用<一个href="http://msdn.microsoft.com/en-us/library/system.servicemodel.configuration.webhttpelement.defaultoutgoingresponseformat.aspx">the DefaultOutgoingResponseFormat 属性是在<一个曝光href="http://msdn.microsoft.com/en-us/library/system.servicemodel.configuration.webhttpelement_properties.aspx"><$c$c>WebHttpElement对此进行控制。更妙的是,你可以公开一个端点,并设置<一个href="http://msdn.microsoft.com/en-us/library/system.servicemodel.configuration.webhttpelement.automaticformatselectionenabled.aspx">the新 AutomaticFormatSelectionEnabled 属性将与正确的格式基于什么样的格式原来的请求是在响应。

This answer above applies strictly to .NET 3.x. If you're using .NET 4.x then you can now use the DefaultOutgoingResponseFormat property that is exposed on WebHttpElement to control this. Even better, you can expose a single endpoint and set the new AutomaticFormatSelectionEnabled property which will respond with the correct format based on what format the original request was in.

这篇关于问题调用WCF服务库从jQuery的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆