Silverlight WCF客户端可以从ASMX Web服务读取异常吗?

时间:2009-12-15 22:33:05

标签: wcf silverlight asmx

我认为没有必要将我的服务升级到WCF,但我已经使用WCF客户端一段时间从.NET 3.5 ASP.NET访问ASMX服务。我想最终我在这种不匹配中遇到了障碍而我刚刚做了 - 但是使用了Silverlight。

使用Silverlight访问ASMX Web服务时,我在弹出窗口中收到如下错误:

  

期间发生了异常   操作,使结果无效。   检查InnerException是否有异常   的信息。

如果我正在调试,我会收到此错误:

 The remote server returned an error: NotFound.

如果我查看Fiddler,异常/错误就可以了:

 <?xml version="1.0" encoding="utf-8"?>
 <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <soap:Body><soap:Fault>
 <faultcode>soap:Server</faultcode>
 <faultstring>Server was unable to process request. ---&gt; ID does not match</faultstring>
 <detail /></soap:Fault></soap:Body></soap:Envelope>

如何在Silverlight客户端中实际获得此异常。

我需要在运行时使用 no fiddler no debugger 来访问错误。

有一个属性includeexceptiondetailinfaults属于web.config中的<behaviors> - 但据我所知,这仅适用于服务器端。

我是否认为我需要将asmx转换为svc以便能够在silverlight客户端获取实际的异常详细信息?

2 个答案:

答案 0 :(得分:0)

没有客户端从Web服务获得异常。 Web服务不会发送异常 - 它们会发送错误。

故障的详细信息包含在故障消息的<detail/>元素中。某些平台(包括WCF)会解析此信息,以便从故障转换为特定于平台的异常。

由于<detail/>元素中没有信息,因此无法进行翻译。

答案 1 :(得分:0)

如果您乐意将asmx SOAP请求包装在自己的IHttpHandler中,则可以在System.Web.Script.Services.ScriptHandlerFactory执行后强制提供Response.StatusCode = 200。这是一个样本;

static void ProcessService(HttpContext context)
{
    //
    // I'm also using this to fake/hide the path of my asmx so that 
    // domain.com/xml becomes the service end-point..
    //
    string asmx = "/Services/Some.Service.asmx";
    string method = context.Request.Path.Substring("/xml".Length);

    //
    // ScriptHandlerFactory and friends are sealed so have to use reflection..
    //
    IHttpHandlerFactory fact = (IHttpHandlerFactory)Activator.CreateInstance(Type.GetType("System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions"));
    Type vpt = Type.GetType("System.Web.VirtualPath, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
    System.Reflection.MethodInfo mi = vpt.GetMethod("Create", new Type[] { typeof(string) });
    object vp = mi.Invoke(null, new object[] { context.Request.Path });
    System.Reflection.FieldInfo fi = context.Request.GetType().GetField("_pathInfo", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
    System.Reflection.FieldInfo _virtualPath = vpt.GetField("_virtualPath", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
    _virtualPath.SetValue(vp, method);
    fi.SetValue(context.Request, vp);
    IHttpHandler handler = fact.GetHandler(context, context.Request.RequestType, asmx, context.Server.MapPath(asmx));

    try
    {
        // This will trap your asmx Exception and output 500 status and soap fault
        handler.ProcessRequest(context); 

        // force 200 status for Silverlight to receive fault code
        context.Response.StatusCode = 200;

        context.ApplicationInstance.CompleteRequest();
    }
    finally
    {
        fact.ReleaseHandler(handler);
    }
}