จะจับข้อยกเว้นทั้งหมดใน WCF แต่รวมข้อมูลที่กำหนดเองได้อย่างไร

ฉันกำลังทำงานในโปรเจ็กต์ที่ใช้การเรียก WCF หลายครั้งเพื่อดำเนินการตามขั้นตอน การโทรครั้งแรกจะส่งกลับ ID เฉพาะ (Guid) ซึ่งต้องระบุการโทรต่อไปนี้ทั้งหมด ฝั่งเซิร์ฟเวอร์ การโทรแต่ละครั้งจะถูกบันทึกพร้อมกับ ID เฉพาะนั้นเพื่อให้สามารถดูหลักสูตรของขั้นตอนเดียวได้ (สมมติว่าไคลเอ็นต์สามารถเริ่มขั้นตอนเหล่านั้นหลายขั้นตอนพร้อมกันได้ และปลอดภัยสำหรับเธรด)< /em>.

ตัวอย่างฝั่งไคลเอ็นต์จะมีลักษณะดังนี้:

string clientName = GetClientName();
Guid uniqueId = wcfClient.Begin(clientName);
object data = wcfClient.GetData(clientName, uniqueId);

object processedData = ProcessDataLocally(data);

bool success = wcfClient.confirmDataValidity(clientName, uniqueId, processedData);

// ...

wcfClient.End(clientName, uniqueId);

หากมีสิ่งผิดปกติเกิดขึ้นบนฝั่งเซิร์ฟเวอร์ ฉันต้องการให้ระบบบันทึกข้อมูลนั้นด้วย โดยใช้รหัสเฉพาะที่มอบให้กับการโทรที่ผิดพลาด เพื่อจุดประสงค์นั้น ฉันทำให้วิธีการบริการทั้งหมดมีฟังก์ชันดังต่อไปนี้:

private T DoProcess<T>(Guid uniqueId, Func<T> process)
{
    try
    {
        return process();
    }
    catch(Exception ex)
    {
        Log(ex, uniqueId);

        throw; // or throw the same thing every time, if the client
               // shouldn't know the details
    }
}

public object GetData(string clientName, Guid uniqueId)
{
    return DoProcess(uniqueId, () =>
    {
        object data;

        // Generate data

        return data;
    });
}

อย่างไรก็ตาม ดูเหมือนว่าการทำเช่นนี้ไม่ได้ตรวจพบข้อผิดพลาดที่อาจเกิดขึ้นทั้งหมด (เช่น หากการเชื่อมต่อหมดเวลา)

ฉันอ่านเกี่ยวกับการใช้อินเทอร์เฟซ IErrorHandler และการแนบไปกับบริการ แม้ว่าสิ่งนี้ดูเหมือนจะตรวจจับข้อผิดพลาดทั้งหมดได้ แต่ดูเหมือนว่าจะไม่มีทางส่งข้อมูลไปให้ข้อผิดพลาดอื่นใดได้นอกจากข้อยกเว้น เช่น รหัสเฉพาะ ดังนั้นจึงไม่มีวิธีบันทึก ID

เป็นไปได้หรือไม่ที่จะตรวจจับข้อยกเว้นทั้งหมดและรวมข้อมูลที่ถูกส่งผ่านไปยังวิธีการที่ข้อยกเว้นถูกส่งออกไป?


person George T    schedule 18.08.2016    source แหล่งที่มา
comment
stackoverflow.com/questions/3666516/   -  person William Xifaras    schedule 18.08.2016


คำตอบ (1)


ข้อยกเว้นเช่นการหมดเวลาการเชื่อมต่อไม่ได้มาถึงบริการ ดังนั้นจึงไม่มีทางที่จะตรวจจับสิ่งนั้นได้ที่ฝั่งบริการ

ด้วยเหตุนี้ คุณสามารถใช้ IExtension เพื่อเพิ่มข้อมูลเพิ่มเติมให้กับ OperationContext ปัจจุบันได้ รูปแบบพื้นฐานสำหรับสิ่งนั้นมีดังนี้:

public class OperationContextExtension : IExtension<OperationContext>
{
    private readonly Dictionary<string, object> extraInfo;

    public OperationContextExtension ()
    {
        extraInfo = new Dictionary<string, object>();
    }

    public static OperationContextExtension Current
    {
        get
        {
            OperationContextExtension c = OperationContext.Current.Extensions.Find<OperationContextExtension>();
            if (c == null)
            {
                c = new OperationContextExtension ();
                OperationContext.Current.Extensions.Add(c);
            }
            return c;
        }
    }

    public Dictionary<string, object> Extras
    {
        get { return extraInfo; }
    }

    public void Attach(OperationContext owner) { }

    public void Detach(OperationContext owner) { }
}

จากนั้นใช้คลาสนั้นในการใช้งาน IErrorHandler :

class FaultErrorHandler : IErrorHandler
{
    public bool HandleError(Exception error)
    {
        return false;
    }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
      Guid ID = OperationContextExtension.Current.Extras["uniqueId"] as Guid;

      LogIt(error.ToString() + ID);
    }
}

จากนั้นใน GetData

public object GetData(string clientName, Guid uniqueId)
{
    OperationContextExtension.Current.Extras["uniqueId"] = uniqueId;
    return DoProcess(uniqueId, () =>
    {
        object data;

        // Generate data

        return data;
    });
}
person Serve Laurijssen    schedule 18.08.2016
comment
Current เป็นฟิลด์คงที่ ปลอดภัยไหมที่จะใช้ในขณะที่สามารถโทรหลายสายพร้อมกันได้? - person George T; 30.08.2016
comment
ใช่ ค่าแวดล้อมประเภทนี้เป็นเรื่องธรรมดาใน WCF ทุกเธรดจะได้รับค่าที่แตกต่างกัน (หากคุณกำหนดค่า PerCall หรือ PerSession) - person Serve Laurijssen; 31.08.2016