2012-04-20 60 views
10

Tôi có dịch vụ WCF với một số phương pháp. Tôi muốn đăng nhập yêu cầu thô đến từ khách hàng bất kể thông tin này đã được gửi như thế nào. Một phương pháp chấp nhận dữ liệu như một chuỗi truy vấn (Nghiêm hỗ trợ di sản) mà tôi có thể đăng nhập sử dụng:Cách đăng nhập yêu cầu thô trong dịch vụ WCF

OperationContext.Current.IncomingMessageHeaders.To.AbsoluteUri 

Đó là đủ trong kịch bản đó, nhưng các phương pháp khác cho phép khách hàng để gửi dữ liệu dạng XML sử dụng một lớp proxy tạo bởi svcutil.exe. Trong trường hợp này, tôi đã tìm thấy dữ liệu tôi muốn trong phần s: Nội dung của:

OperationContext.Current.RequestContext.RequestMessage 

Thật không may, cho dù tôi có cố gắng không thể tạo bản sao đệm của thư trước khi nó được đọc. Dưới đây là một ví dụ:

public CascadeResponse SendCustomer(Customer c) 
    { 
     Message msg = OperationContext.Current.RequestContext.RequestMessage.CreateBufferedCopy(Int32.MaxValue).CreateMessage(); 
     LogMessage(msg); 
     // Now that the request is logged, get on with the rest 
    } 

Trên dòng đầu tiên của SendCustomer, tuy nhiên, tôi nhận được lỗi sau:

Thông báo này không thể hỗ trợ hoạt động bởi vì nó đã được đọc.

Đây là điểm tôi tạo bản sao đệm, chắc chắn? Tôi đoán rằng tôi đang làm điều gì đó không chính xác ở đây.

Edit:

Ok, vì vậy phương pháp hiện nay là như thế này:

public CascadeResponse SendCustomer(Message requestMessage) 
    { 
     Message msg = OperationContext.Current.RequestContext.RequestMessage.CreateBufferedCopy(Int32.MaxValue).CreateMessage(); 
     LogMessage(msg); 
     // Now that the request is logged, get on with the rest   
     Customer c = msg.GetBody<Customer>(); 
     string clientKey = "1111"; // This should be the clientKey string passed to the function along with the customer 
     return SendLead(c, clientKey); 
    } 

Vấn đề của tôi là tôi không biết làm thế nào để có được khách hàng và ClientKey gửi như những thực thể riêng biệt. Tôi có thể biến clientKey thành thuộc tính của Khách hàng (hoặc tạo một đối tượng tùy chỉnh để chuyển dữ liệu và chứa Khách hàng và ClientKey làm thuộc tính), nhưng tôi muốn tránh điều đó nếu có thể, vì đây là bản nâng cấp của hệ thống cũ đã hoạt động theo cách này.

Tôi cũng gặp sự cố khi sử dụng svcUtil.exe để tạo các lớp proxy của mình - Tôi cho rằng chữ ký phương thức trên có nghĩa là dịch vụ của tôi sẽ không còn quảng cáo chữ ký chính xác để gửi yêu cầu không? Không chắc chắn nếu điều đó là đủ rõ ràng - nếu phương thức nhập liệu duy nhất của tôi chấp nhận một đối tượng Message, làm thế nào để máy khách của tôi biết gửi một Customer và một ClientKey?

+0

Bất kỳ lý do nào khiến bạn không thể sử dụng chức năng dò tìm tích hợp trong WCF? http://msdn.microsoft.com/en-us/library/ms733025.aspx – DaveRead

+0

@DaveRead Chủ yếu là tôi đã không nhận thức được nó - điều này cho phép tôi lưu nhật ký của tôi vào cơ sở dữ liệu? – Maloric

+0

Không ra khỏi hộp nhưng bạn có thể tạo TraceListener tùy chỉnh của riêng bạn, xem bài viết này để biết chi tiết: http://msdn.microsoft.com/en-gb/magazine/cc300790.aspx – DaveRead

Trả lời

19

Tôi tìm thấy một giải pháp mà những người khác cũng có thể thấy hữu ích. Tạo một MessageInspector cho phép bạn đính kèm mã để các "AfterReceiveRequest" và "BeforeSendReply" sự kiện, theo như sau:

public class MessageInspector : IDispatchMessageInspector 
{ 
    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) 
    { 
     MessageBuffer buffer = request.CreateBufferedCopy(Int32.MaxValue); 
     request = buffer.CreateMessage(); 
     LogMessage("Received:\n{0}", buffer.CreateMessage().ToString()); 
     return null; 
    } 

    public void BeforeSendReply(ref Message reply, object correlationState) 
    { 
     MessageBuffer buffer = reply.CreateBufferedCopy(Int32.MaxValue); 
     reply = buffer.CreateMessage(); 
     LogMessage("Sending:\n{0}", buffer.CreateMessage().ToString()); 
    } 
} 

Có một full tutorial for setting up message inspectors fo wcf here. Tôi sẽ nói cẩn thận để kiểm tra tên hội đủ điều kiện của bạn khi bạn thêm phần mở rộng hành vi vào app.config/web.config của mình.

Hy vọng người khác thấy điều này hữu ích.

2

Để cho bạn để đạt được nêu trên bạn cần thay đổi phương pháp của bạn như hình dưới đây:

public CascadeResponse SendCustomer(Message requestMessage) 
    { 
     Message msg = OperationContext.Current.RequestContext.RequestMessage.CreateBufferedCopy(Int32.MaxValue).CreateMessage(); 
     LogMessage(msg); 
     // Now that the request is logged, get on with the rest   
     Customer c = msg.GetBody<Customer>(); 
    } 

Thông tin thêm về Using Message Class

+0

Cảm ơn, điều này giúp tôi đi đúng hướng nhưng tôi nhận được một loạt lỗi khi sử dụng svcutil.exe để tạo các lớp proxy yêu cầu. 'Không thể nhập wsdl: binding' ' Không thể nhập wsdl: binding' ... và như vậy trên Ngoài ra, tôi không chắc chắn cách truy xuất các đối tượng bổ sung từ phần thân yêu cầu (ví dụ của tôi chỉ chứa một đối tượng) nhưng mã thực tế có một chuỗi bổ sung xác định máy khách). Tôi sẽ xem xét lại vào Thứ Hai, nhưng cảm ơn sự giúp đỡ của bạn cho đến thời điểm này. – Maloric

2

Tôi nghĩ bạn có thể sử dụng ...ToString() phương pháp và những gì nó sẽ làm là viết lại thông điệp nội bộ:

string soap = OperationContext.Current.RequestContext.RequestMessage.ToString(); 

Nhìn bên trong phương pháp ToString() ...;)

0

Trong VS2015 trên một dự án dịch vụ WCF, bạn có thể nhấp chuột phải vào web .config để chỉnh sửa cấu hình WCF. Từ đây, bạn có thể bật chẩn đoán để nhận thông báo thô được ghi lại.

+0

Bạn có thể giải thích chi tiết về điều này và chỉ định chính xác cách thức và cài đặt nào không? Chỉ cần làm cho tuyên bố này là không đủ để có ích. –

Các vấn đề liên quan