Может ли клиент Silverlight WCF считывать исключения из веб-службы ASMX? - PullRequest
0 голосов
/ 16 декабря 2009

Я не видел необходимости обновлять свои службы до 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.

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

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

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

Ответы [ 2 ]

0 голосов
/ 23 декабря 2009

Если вы счастливы заключить SOAP-запрос asmx в свой собственный 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);
    }
}
0 голосов
/ 16 декабря 2009

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

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

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

...