2009-01-24 30 views
13

oturum dışı durumları günlüğe kaydederek istemci tarafında javascript'ten alınabilen web hizmetlerini kullanmak için [System.Web.Script.Services.ScriptService] etiketini kullanıyorum. İhtiyacım olan şey, bu yöntemlerde işlenmemiş istisnaları global olarak günlüğe kaydetmenin bir yoludur. İstemci tarafında, hata geri çağrısı alıyorum ve oradan devam edebilir, ancak özel durumu günlüğe kaydetmek için sunucu tarafında bir yakalamaya ihtiyacım var.Global olarak, ASP.NET [ScriptService] hizmetlerinden

bu url adam: http://ayende.com/Blog/archive/2008/01/06/ASP.Net-Ajax-Error-Handling-and-WTF.aspx

bu yapılamaz düşündürmektedir.

Bu doğru mu? Tüm sistemdeki her bir webmethod'a gitmeyi ve bir bütün olarak yöntemi yakalamayı/kullanmayı denemeliyim.

cevap

14

Web hizmeti yöntemi tarafından atılan özel durum iletisini, yığın izlemeyi ve özel durum türünü yakalamak için bir HTTP modülü kullanabilirsiniz.

İlk bazı arka plan ... özel hata kapatıp web hizmet ise bir web hizmeti yöntemi HTTP yanıt 500.

  • bir durum kodu olan bir istisna atar

    • Özel durum iletisini döndürecek ve istemciyi JSON olarak yığın yığınına gönderecektir.Örneğin: özel hatalar ardından olduğunda web hizmeti istemcisi varsayılan bir mesaj döner ve yığın iz ve istisna tipini kaldırır {"Message":"Exception message","StackTrace":" at WebApplication.HelloService.HelloWorld() in C:\Projects\Stackoverflow Examples\WebApplication\WebApplication\HelloService.asmx.cs:line 22","ExceptionType":"System.ApplicationException"}


    • : Yani
      {"Message":"There was an error processing the request.","StackTrace":"","ExceptionType":""}

    ne yapmanız gereken, web hizmeti için özel hatalar ayarlamak ve bir HTTP modülüne takmaktır. Bu, şu HTTP modülüne bağlanır:

    1. C istek bir web hizmeti yöntemi
    2. için geçerli olup olmadığını denetler Bir özel durumun atılıp atılmadığını denetler - yani, bir durum kodu 500 döndürülüyor
    3. 1) ve 2) doğruysa, o zaman müşteriye gönderilen ve aşağıda kod yapar bir HTTP modülü örneğidir

    varsayılan JSON ile değiştirin:

    using System; 
    using System.Collections.Generic; 
    using System.IO; 
    using System.Text; 
    using System.Web; 
    
    public class ErrorHandlerModule : IHttpModule { 
    
        public void Init(HttpApplication context) { 
        context.PostRequestHandlerExecute += OnPostRequestHandlerExecute; 
        context.EndRequest += OnEndRequest; 
        } 
    
        static void OnPostRequestHandlerExecute(object sender, EventArgs e) { 
        HttpApplication context = (HttpApplication) sender; 
        // TODO: Update with the correct check for your application 
        if (context.Request.Path.StartsWith("/HelloService.asmx") 
         && context.Response.StatusCode == 500) { 
         context.Response.Filter = 
         new ErrorHandlerFilter(context.Response.Filter); 
         context.EndRequest += OnEndRequest; 
        } 
        } 
    
        static void OnEndRequest(object sender, EventArgs e) { 
        HttpApplication context = (HttpApplication) sender; 
        ErrorHandlerFilter errorHandlerFilter = 
         context.Response.Filter as ErrorHandlerFilter; 
        if (errorHandlerFilter == null) { 
         return; 
        } 
    
        string originalContent = 
         Encoding.UTF8.GetString(
         errorHandlerFilter.OriginalBytesWritten.ToArray()); 
    
        // If customErrors are Off then originalContent will contain JSON with 
        // the original exception message, stack trace and exception type. 
    
        // TODO: log the exception 
        } 
    
        public void Dispose() { } 
    }

    Bu modül gönderilen içeriği geçersiz kılmak için aşağıdaki filtreyi kullanır İstemci ve orijinal baytları saklamak n, durum mesajı) iz ve özel türü yığını:

    public class ErrorHandlerFilter : Stream { 
    
        private readonly Stream _responseFilter; 
    
        public List OriginalBytesWritten { get; private set; } 
    
        private const string Content = 
        "{\"Message\":\"There was an error processing the request.\"" + 
        ",\"StackTrace\":\"\",\"ExceptionType\":\"\"}"; 
    
        public ErrorHandlerFilter(Stream responseFilter) { 
        _responseFilter = responseFilter; 
        OriginalBytesWritten = new List(); 
        } 
    
        public override void Flush() { 
        byte[] bytes = Encoding.UTF8.GetBytes(Content); 
        _responseFilter.Write(bytes, 0, bytes.Length); 
        _responseFilter.Flush(); 
        } 
    
        public override long Seek(long offset, SeekOrigin origin) { 
        return _responseFilter.Seek(offset, origin); 
        } 
    
        public override void SetLength(long value) { 
        _responseFilter.SetLength(value); 
        } 
    
        public override int Read(byte[] buffer, int offset, int count) { 
        return _responseFilter.Read(buffer, offset, count); 
        } 
    
        public override void Write(byte[] buffer, int offset, int count) { 
        for (int i = offset; i < offset + count; i++) { 
         OriginalBytesWritten.Add(buffer[i]); 
        } 
        } 
    
        public override bool CanRead { 
        get { return _responseFilter.CanRead; } 
        } 
    
        public override bool CanSeek { 
        get { return _responseFilter.CanSeek; } 
        } 
    
        public override bool CanWrite { 
        get { return _responseFilter.CanWrite; } 
        } 
    
        public override long Length { 
        get { return _responseFilter.Length; } 
        } 
    
        public override long Position { 
        get { return _responseFilter.Position; } 
        set { _responseFilter.Position = value; } 
        } 
    }

    Bu yöntem, bir web hizmet kapatılmalıdır özel hataları gerektirir. Muhtemelen uygulamanın geri kalanı için özel hatalar tutmak isteyebilirsiniz, böylece web hizmetleri bir alt dizine yerleştirilmelidir. Özel hatalar, bu dizinde yalnızca üst ayarı geçersiz kılan bir web.config kullanılarak kapatılabilir.

  • +0

    Mevcut projemde bununla birlikte devam etmeme rağmen, bu muhtemelen tüm bu hataları güvenilir bir şekilde yakalamak için tek yoldur. – Clyde

    +0

    Bunu denedim, ancak bir şekilde bağlamım.Response.Filter.length, 'System.NotSupportedException' türünde bir istisna attı. Sadece işe yaramıyor. Bence çok yakın, çıkışım aynen söylediğin gibi. ve 500 durum kodum var. – maxisam

    -1

    ASP.Net'de, blog yayınının bu işe yaramayacağını öne sürmesine rağmen, bir koşulu ele geçirme özel durumlarını global error handler kullanarak yakalamak mümkündür, ancak bu yaklaşımı bir şekilde yeniden denemeye çalışırken denemenizi deneyebilirsiniz.

    Başka bir fikir, ASP.Net'in yardımcı olabilecek (Hata Günlüğü Modülleri ve İşleyicileri) açık kaynağına veya bu topluluktaki bir kişinin bir fikri olabileceğine bakmaktır.

    +1

    Evet, sorunu gerçekten anladığınızdan emin değilim. İstisna *, * yakalama şansı yakalamadan önce yakalanan ASP.NET komut dosyası servis kodu tarafından yakalandı. Yani global hata işleyicisi çalışmıyor. Çerçeve bir istemci tarafında hata mesajı gönderir, böylece bir ileti görüntüleyebilirim, ancak – Clyde

    +0

    sunucu kancası yok Ancak, elmah bağlantısı ilginç ... Bunu kontrol etmek için – Clyde

    +0

    ikinci ELMAH'm var. Bunu tam olarak bu amaçla kullanıyorum. –

    1

    Bu sorunun cevabını vermediğini biliyorum, ama bunu bulmak için bir an önce kendi arayışıma girdim ve boşaldım. Her web servis çağrısını bir try/catch'a sarmakla sona erdi ve catch, hata kaydedicimizi çağırdı. Berbat ama işe yarıyor.

    3

    Depolanan Prosedürü arka planda çalıştırırsınız. Daha sonra, tek bir değişken için 1'den fazla değer döndürür. Bu nedenle, bir çakışma meydana gelir ve bu hata atılır.

    İlgili konular