我在这个头上撕裂了我的头发,所以忍受我(这是一个很长的篇幅)。

基本信息

> ASP.NET 3.5与ASP.NET兼容模式下的WCF服务
>将jQuery与this service proxy用于AJAX请求
>自定义IErrorHandler和IServiceBehavior实现来捕获异常并提供Faults,将其序列化为JSON
我正在本地使用Cassini进行测试(我看到一些线程讨论了在本地调试时出现的问题,但在生产环境中工作正常)。

我遇到的问题是,当我的WCF服务抛出异常时,$ .ajax调用的成功处理程序被触发。响应为空,状态文本为“成功”,响应代码为202 / Accepted。

IErrorHandler实现确实被使用,因为我可以通过它来查看创建的FaultMessage。最后发生的是,成功回调会引发错误,因为当期望JSON字符串时,响应文本为空。错误回调从不触发。

提供一点洞察的一件事是从端点行为中删除enableWebScript选项。当我这样做时,发生了两件事情:

>回复不再包裹(即没有{d:“result”},只是“结果”)。
>错误回调被触发,但响应只是来自IIS的400 / Bad Request黄屏死机的HTML,而不是我的序列化故障。

我尝试了十大结果中显示的更多内容,或者来自Google的关于随机组合关键字“jquery ajax asp.net wcf faultcontract json”的更多内容,所以如果你计划在谷歌搜索一个答案,不要打扰。我希望有人在这个问题上遇到过这个问题。

最终我想要实现的是:

>能够在WCF方法中抛出任何类型的异常
>使用FaultContact
>捕获ShipmentServiceErrorHandler中的例外
>将序列化的ShipmentServiceFault(作为JSON)返回给客户端。
>调用错误回调,所以我可以处理项目4。

可能与:

> WCF IErrorHandler Extension not returning specified Fault

更新1

我检查了跟踪System.ServiceModel活动的输出,在调用UpdateCountry方法后的一个时刻,抛出异常,消息是

Server returned an invalid SOAP Fault.

就是这样一个内部的异常引发了串行器期望一个不同的根元素,但是我不能破译出很多其他的东西。

更新2

所以有了更多的烦恼,我有一些工作,虽然不是我认为理想的方式。这是我做的:

>删除< enableWebScript />选项从web.config的端点行为部分。
>从服务方法中删除FaultContract属性。
>实现了WebHttpBehavior的一个子类(称为ShipmentServiceWebHttpBehavior),并覆盖了AddServerErrorHandlers函数来添加ShipmentServiceErrorHandler。
>更改了ShipmentServiceErrorHandlerElement以返回一个ShipmentServiceWebHttpBehavior类型的实例,而不是错误处理程序本身。
>移动< errorHandler />从web.config的服务行为部分到端点行为部分。

这不太理想,因为现在WCF忽略了我想要的服务方法的BodyStyle = WebMessageBodyStyle.WrappedRequest(尽管我现在可以完全省略它)。我也必须更改JS服务代理中的一些代码,因为它正在寻找一个包装({d:…})对象的响应。

以下是所有相关代码(ShipmentServiceFault对象非常自我说明)。

服务

我的服务很简单(截断版本):

[ServiceContract(Namespace = "http://removed")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class ShipmentService
{

    [OperationContract]
    [WebInvoke(Method = "POST",ResponseFormat = Webmessageformat.Json,BodyStyle = WebMessageBodyStyle.WrappedRequest)]
    [FaultContract(typeof(ShipmentServiceFault))]
    public string UpdateCountry(Country country)
    {
        var checkName = (country.Name ?? string.Empty).Trim();
        if (string.IsNullOrEmpty(checkName))
            throw new ShipmentServiceException("Country name cannot be empty.");

        // Removed: try updating country in repository (works fine)

        return someHtml; // new country information HTML (works fine)
    }

}

错误处理

IErrorHandler,IServiceBehavior实现如下:

public class ShipmentServiceErrorHandlerElement : BehaviorExtensionElement
{
    protected override object CreateBehavior()
    {
        return new ShipmentServiceErrorHandler();
    }

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

public class ShipmentServiceErrorHandler : IErrorHandler,IServiceBehavior
{
    #region IErrorHandler Members

    public bool HandleError(Exception error)
    {
        // We'll handle the error,we don't need it to propagate.
        return true;
    }

    public void ProvideFault(Exception error,System.ServiceModel.Channels.MessageVersion version,ref System.ServiceModel.Channels.Message fault)
    {
        if (!(error is FaultException))
        {
            ShipmentServiceFault faultDetail = new ShipmentServiceFault
            {
                Reason = error.Message,FaultType = error.GetType().Name
            };

            fault = Message.CreateMessage(version,"",faultDetail,new DataContractJsonSerializer(faultDetail.GetType()));

            this.ApplyJsonSettings(ref fault);
            this.ApplyHttpResponseSettings(ref fault,System.Net.HttpStatusCode.InternalServerError,faultDetail.Reason);
        }
    }

    #endregion

    #region JSON Exception Handling

    protected virtual void ApplyJsonSettings(ref Message fault)
    {
        // Use JSON encoding  
        var jsonFormatting = new WebBodyFormatMessageProperty(WebContentFormat.Json);

        fault.Properties.Add(WebBodyFormatMessageProperty.Name,jsonFormatting);
    }

    protected virtual void ApplyHttpResponseSettings(ref Message fault,System.Net.HttpStatusCode statusCode,string statusDescription)
    {
        var httpResponse = new HttpResponseMessageproperty()
        {
            StatusCode = statusCode,StatusDescription = statusDescription
        };

        httpResponse.Headers[HttpResponseHeader.ContentType] = "application/json";
        httpResponse.Headers["jsonerror"] = "true";

        fault.Properties.Add(HttpResponseMessageProperty.Name,httpResponse);
    }

    #endregion

    #region IServiceBehavior Members

    public void AddBindingParameters(ServiceDescription serviceDescription,System.ServiceModel.ServiceHostBase serviceHostBase,System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints,System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
    {
        // Do nothing
    }

    public void ApplydispatchBehavior(ServiceDescription serviceDescription,System.ServiceModel.ServiceHostBase serviceHostBase)
    {
        IErrorHandler errorHandler = new ShipmentServiceErrorHandler();

        foreach (ChanneldispatcherBase channeldispatcherBase in serviceHostBase.Channeldispatchers)
        {
            Channeldispatcher channeldispatcher = channeldispatcherBase as Channeldispatcher;

            if (channeldispatcher != null)
            {
                channeldispatcher.ErrorHandlers.Add(errorHandler);
            }
        }
    }

    public void Validate(ServiceDescription serviceDescription,System.ServiceModel.ServiceHostBase serviceHostBase)
    {
        // Do nothing
    }

    #endregion
}

JavaScript

调用WCF方法开始于:

function SaveCountry() {
        var data = $('#uxCountryEdit :input').serializeBoundControls();
        ShipmentServiceProxy.invoke('UpdateCountry',{ country: data },function(html) {
            $('#uxCountryGridResponse').html(html);
        },onPageError);
    }

我之前提到的服务代理需要处理很多事情,但是核心是我们来到这里:

$.ajax({
    url: url,data: json,type: "POST",processData: false,contentType: "application/json",timeout: 10000,dataType: "text",// not "json" we'll parse
    success: function(response,textStatus,xhr) {

    },error: function(xhr,status) {                

    }
});

组态

我觉得这里的问题可能在这里,但是我已经尝试了每个组合的设置,我可以在网上找到一个例子。

<system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
    <behaviors>
        <endpointBehaviors>
            <behavior name="Removed.ShipmentServiceAspNetAjaxBehavior">
                <webHttp />
                <enableWebScript />
            </behavior>
        </endpointBehaviors>
        <serviceBehaviors>
            <behavior name="Removed.ShipmentServiceServiceBehavior">
                <serviceMetadata httpGetEnabled="true"/>
                <serviceDebug includeExceptionDetailInFaults="false"/>
                <errorHandler />
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <services>
        <service name="ShipmentService" behaviorConfiguration="Removed.ShipmentServiceServiceBehavior">
            <endpoint address="" 
                behaviorConfiguration="Removed.ShipmentServiceAspNetAjaxBehavior" 
                binding="webHttpBinding" 
                contract="ShipmentService" />
        </service>
    </services>
    <extensions>
        <behaviorExtensions>
            <add name="errorHandler" type="Removed.Services.ShipmentServiceErrorHandlerElement,Removed,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null"/>
        </behaviorExtensions>
    </extensions>
</system.serviceModel>

笔记

我注意到这个问题正在获得一些喜爱。我找到了解决这个问题的办法,希望在找到一段时间的时候提供一个答案。敬请关注!

解决方法

我不熟悉ASP或WCF,但我对jQuery非常熟悉。关于您的问题的一个事情是,您的服务正在返回202当抛出异常时成功。 jQuery根据从服务器返回的HTTP状态代码选择要调用哪个回调(成功或错误)。 202被认为是一个成功的响应,因此jQuery将会成功。如果你想让jQuery调用错误回调,你需要使你的服务返回一个40x或50x的状态代码。请咨询 http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html以获取HTTP状态代码列表。

当WCF方法抛出异常时,jQuery成功回调用空响应调用的更多相关文章

  1. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  2. 在IOS9中的Cordova应用程序使用JQuery / Javascript的window.history问题

    在两个测试用例中唯一改变的是Cordova.js.解决方法我看到这是几个星期前,但我会发布这个,以防其他人遇到它.听起来它可能与iOS9中的哈希更改生成的导航事件有关.如果是这样,可以将其添加到index.html以禁用哈希侦听:

  3. iOS 5上的jQuery事件

    解决方法在Apple开发论坛上由一个人回答:我需要在将元素添加到DOM之后才绑定(),如下所示:

  4. 从Android应用程序中消耗WCF Web服务?

    我想从Android应用程序中使用WCFWeb服务.我曾经使用过.asmxweb服务,但我不知道如何在Android应用程序中使用SCFWeb服务.我用谷歌搜索它但没有找到任何东西.如果有人做过,请帮助我.提前致谢.解决方法Hereisanarticleexplaininghowtoconsumewebservicewithandroidingeneral当涉及到WCF并且可以与您想要小心的jav

  5. android – Phonegap本地构建 – jquery ajax错误:readystate 0 responsetext status 0 statustext error

    解决方法您是否在索引文件中包含了内容安全元标记?

  6. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  7. 设置焦点到输入框和显示Android键盘使用jquery手机在pageshow

    我正在设置焦点到输入框,并显示Android键盘使用jquery手机网页显示.我从Web上尝试过很多选项.但是没有一个在模拟器和移动设备中都能按预期工作.这是代码:查找屏幕截图以供参考请咨询…解决方法对我有用的解决方案

  8. android – 如何在焦点()上以编程方式隐藏jquery mobile中的键盘

    我想在Focus()上隐藏键盘,但是当$(“.ui-input-text”).focus();它会自动打开键盘.我只是想隐藏在特定的屏幕上,我用document.activeElement.blur()测试;但它也没有关注()输入.解决方法提交表单时,iOS键盘可能不会自动关闭.这是一个非常实用的问题,因为不应要求用户手动关闭键盘,否则他们不会期望需要这样做.可以通过调用document.acti

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. jQuery实现简单的抽奖游戏

    这篇文章主要为大家详细介绍了jQuery实现简单的抽奖游戏,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

随机推荐

  1. jquery-plugins – 是否可以使用猫头鹰旋转木马实现循环/无限轮播?

    我正在使用猫头鹰旋转木马,它的工作完美,除了它不支持循环/无限滚动.我没有搜索google和stackoverflow的想法,没有运气.有没有人在猫头鹰旋转木马上实现圆形/无限滚动?

  2. jQuery动态输入字段焦点

    我想使用以下jQuery向我的页面动态添加一个输入字段:在这样做之后,我希望输入字段具有闪烁的文本光标的焦点,所以我想在创建后立即输入.有人可以告诉我我该怎么办?

  3. jquery – 为什么$(window).height()这样错了?

    我试图获取当前浏览器的视口高度,使用但我得到的价值观太低了.当视口高度高达850px时,我从height()获取大约350或400像素的值.这是怎么回事?

  4. jquery – 如果在此div之外和其他draggables内部(使用无效和有效的还原选项),则可拖动恢复

    例如这样但是由于明显的原因,这不行.我可以说这个吗?

  5. 创建一个jQueryUI 1.8按钮菜单

    现在jQueryUI1.8已经出来了,我正在浏览更新,并且遇到了新的Buttonwidget,特别是SplitButtonwithadropdown的演示之一.这个演示似乎表明Buttonwidget可以在这里创建一个下拉菜单.作为讨论的问题,我想知道使用这个新的Button小部件来创建一个下拉菜单有什么方法.干杯.解决方法您必须在按钮下方列出一个列表,方式类似于此处为自动完成提供的演示:http

  6. 灰色divs使用JQuery

    我试图使用这个代码:为了淡出一大堆名为MySelectorDiv的div,唯一的是,它只会淡出第一个而不是所有的div,为什么呢?

  7. 使用jQuery动态插入到列表中

    我有两个订单列表在彼此旁边.当我从一个列表中选出一个节点时,我想按照字母顺序插入到另一个列表中.抓住的是我想要把一个元素放在另一个列表中,而不刷新整个列表.奇怪的是,当我插入到右边的列表中,它工作正常,但是当我插入到左边的列表中时,顺序永远不会出来.我也尝试将所有内容读入数组,并将其排序在一起,以防止children()方法没有按照显示顺序返回任何东西,但是我仍然得到相同的结果.这是我的jQuer

  8. 没有回应MediaWiki API使用jQuery

    我试图从维基百科获取一些内容作为JSON:但我没有回应.如果我粘贴到浏览器的地址栏,就像我得到预期的内容.怎么了?解决方法您需要通过添加&callback=?来触发具有$.getJSON()的JSONP行为?在querystring上,像这样:Youcantestithere.没有使用JSONP,你正在击中same-originpolicy,阻止XmlHttpRequest获取任何数据.

  9. jQuery Ajax请求每30秒

    我有这段代码,但是有些人在我的网站上的值可能会改变.我需要每30秒钟更新一次#financediv.这可以做吗解决方法您可以将代码放在单独的函数中,如下所示:然后每30秒建立一个定时器调用该函数:祝你好运!总结以上是DEVMAX为你收集整理的jQueryAjax请求每30秒全部内容。如果觉得DEVMAX网站内容还不错,欢迎将DEVMAX网站推荐给好友。

  10. jquery – keypress事件在IE和Chrome中不工作,但在FF工作

    任何想法为什么会这样发生?我通常认为Chrome会更加宽容代码?这是我的按键键.我错过了什么吗?右图();和leftimage();是应该工作的功能,因为我在其他地方使用这些功能谢谢您的帮助!

返回
顶部