Может ли клиент Silverlight WCF читать исключения из веб-службы ASMX?

Я не видел необходимости обновлять свои службы до WCF, но я уже некоторое время использую клиентов WCF для доступа к службам ASMX из .NET 3.5 ASP.NET. Я подумал, что в конце концов я наткнусь на стену из-за этого несоответствия, и я просто сделал это, но с Silverlight.

При использовании Silverlight для доступа к веб-службам ASMX я получаю во всплывающем окне такую ​​ошибку:

Во время операции возникла исключительная ситуация, в результате чего результат стал недействительным. Подробности об исключении см. В 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.

Мне нужно, чтобы ошибка была доступна во время выполнения при отсутствии скрипачей и без отладчик.

Существует свойство includeexceptiondetailinfaults, которое принадлежит <behaviors> в web.config - но это только для стороны сервера, насколько я могу судить.

Правильно ли я предполагаю, что мне нужно будет преобразовать мой asmx в svc, чтобы иметь возможность получать фактические данные об исключении в клиенте silverlight?


person Simon_Weaver    schedule 15.12.2009    source источник


Ответы (2)


Если вы счастливы обернуть запрос asmx SOAP в свой собственный IHttpHandler, вы можете принудительно передать Response.StatusCode = 200 после того, как System.Web.Script.Services.ScriptHandlerFactory выполнит свою работу. Вот образец;

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);
    }
}
person Sichbo    schedule 23.12.2009
comment
Я думаю, проще переключиться на настоящий WCF! спасибо за обработчик - person Simon_Weaver; 24.12.2009

Ни один клиент никогда не получает исключений от веб-служб. Веб-службы не отправляют исключения - они отправляют ошибки.

Подробная информация об ошибке содержится в элементе <detail/> сообщения об ошибке. некоторые платформы, включая WCF, анализируют эту информацию, чтобы преобразовать ошибку в исключение, зависящее от платформы.

Поскольку в элементе <detail/> нет информации, перевод вряд ли произойдет.

person John Saunders    schedule 15.12.2009
comment
я сказал исключение / ошибка :-), поэтому мне нужно будет преобразовать в .svc, чтобы получить подробную информацию о неисправности? - person Simon_Weaver; 16.12.2009