I have a requirement for a WCF service I've created to be able to go into "read only" mode. While in this state it will not service requests for calls that would make changes to the database (like creating an order) but will only service read-only requests (like authenticate user). If it receives a request that it will not service, it needs to pass back a friendly message and code (e.g. CODE: 100, DESCRIPTION: "Service is in read only mode and cannot service this request").
I have close to 100 different calls and would like to implement a solution that can be made in one place (like an IDispatchMessageInspector) but I don't see a way to provide a response to any intercepted WCF messages. I have a standard response type that I send back on ALL requests and would like to send that back in these situations as well. The type is named ServiceResponse and has a messages collection. which is a class of Codes and Descriptions.
public class ServiceResponse
{
public List<Message> Messages {get; set;}
}
public class Message
{
public string Code {get; set;}
public string Description {get; set;}
}
Can someone provide me with a direction on how to do this? I have exhausted all of my searching options.
Even if there is just a way in WCF to hand create the SOAP I'm sending back, that's fine as long as I don't have to handle the read-only check / response in every single service call.
Thanks!
I see a couple of choices. 1) add the functionality into the service implementations (100 of them), 2) find an aspect-oriented tool to intercept the service invocation at runtime and execute different code, or 3) intercept all the wcf requests using a custom HTTPHandler. In the handler you can process the request and return a response to the client. Here are some links which might help
http://blogs.msdn.com/b/wenlong/archive/2007/09/18/how-to-use-asmx-extension-to-handle-wcf-requests.aspx
HttpHandler to hook the *.svc requests
You could achieve this with a custom ServiceAuthorizationManager.
The idea would be
Add a custom attribute to each class that you want to disable when in read only mode
In the custom ServiceAuthorizationManager, check to see if the service is in read only mode. If it is, check for the custom attribute on the method you are trying to call. The method is indicated by the request message action header. The type of the service can be found from the OperationContext.InstanceContext (I think - I can't remember exactly what property)
If you find the attribute, throw a fault exception with the right error message.
Related
I have a web service called S
My client have a web service called C
My client send a request to my web service (web service S)
Web service S will send a response to client ( C )
After that, my service (S) will create 1 invoice message and send it to client web service (C)
Client web service return result to my web service (S)
How to implement it?
As I understand, you want to return a response to client app, but still continue with some processing.
There are a few possibilities here:
Start a new thread in 2., that will create the invoice and send it to client WS. This however can be error-prone - your web service might die or be shut down in the middle of creating the invoice and client WS will never know.
Use something like hangfire to schedule invoice creation. Hangfire stores scheduled tasks in DB, so it will be eventually executed, even in case of failure. This does not require additional configuration other than setting up the backend db. Processing happens in the same hosting process of your Service.
Use a ServiceBus or MSMQ - the idea is simmilar as with Hangfire - you send a message (saying like "create invoice with parameters X") to the Bus, the Bus makes sure the message gets delivered to anyone that listens for it. Then you register a listener that would handle that kind of message and create the invoice. This would require more work, since you have to choose the Service Bus engine, take a moment to understand it, install, configure, etc.
This is a good case for a domain event. I don't know what the first request is - perhaps placing an order?
When the order is placed then you would raise an event indicating that an order was placed. The event could contain either some information about the order or a reference (id) that can be used to retrieve it. Then other listeners would respond accordingly.
One benefit is that it keeps different parts of your application decoupled. For example, the class that submits an order doesn't need to know that there's going to be an invoice. It just raises an event indicating that an order has been placed and then goes on its way.
That becomes even more important if you want to have multiple behaviors when an order is placed. Perhaps you also want to send an email confirming that your received the order. Now you can add that additional behavior as an event listener with no modification to the code that places the order.
Also, your application could grow so that perhaps there's another service for placing orders. (I'm running with "placing orders" although I don't know what the specific event is.) You don't want multiple points in your application that follow all of the post-ordering steps. If those steps change then you'd have to modify code in all of those places. Instead you just raise the event.
Here's a popular article that describes the concept well. There are numerous implementations of an event bus. Here's one.
In pseudocode, you could now have a few event handlers, each of which is completely decoupled from your ordering code.
The event itself is raised immediately after the order is submitted.
var order = SubmitOrder(info);
eventBus.Raise(new OrderSubmitEvent(order));
Then you have some event handlers which are registered to respond to that event.
public class SendInvoiceOrderEventHandler : IEventHandler<OrderSubmitEVent>
{
public void HandleEvent(OrderSubmitEvent e)
{
//e contains details about the order. Send an invoice request
}
}
public class SendConfirmationOrderEventHandler : IEventHandler<OrderSubmitEVent>
{
public void HandleEvent(OrderSubmitEvent e)
{
//send an email confirmation
}
}
I am new to WCF services and currently testing out things.
I have got a little REST API, which has several methods. Some of them require a user context (session), some others don't. At login, each user gets a session token. The client should supply this token and his user ID on every request via HTTP headers.
At the moment, I wrote a method for getting those two headers and validate the session, calling it on every method which will need a user context. This seems kinda nasty if the API gets bigger.
Is there a better approach for doing this?
You can leverage of following solutions:
Custom class deriving IClientMessageInspector/IDispatchMessageInspector for client and service respectively. Then you add its instance to MessageInspectors. Advantage of having messageInspector is that it's applied to single endpoint so regardless of having many endpoints exposed (both SOAP and REST), messageInspector can be associated only with single one. Whenever message is either received or sent, AfterReceive or BeforeSent method is invoked respectively. There you retrieve headers and if token does not match any expected you can throw an exception. Such a way out provides separation between exposed contract and background checks such as token validation.
Custom class deriving IOperationInvoker. Within custom operation invoker you explicitly call method and thanks to it you can examine headers (OperationContext.Current.IncomingMessage) before any method gets invoced.
I brought up only concepts, extensive information and examples can be looked up on Internet.
Based on the processing of the incoming request I have to store the original (unserialized) message as string to a database.
So far I implemented a DispatchMessageInspector and a ServiceBehavior that I used to decorate my service implementation. My DispatchMessageInspector has a property to which I store the message string. My service implementation includes some business rules that check the request and if this check fails I'd like to store the original message.
How can I achieve to access the message string property of my DispatchMessageInspector from the service implementation in an elegant way?
You can add a Message Property containing the raw message in a form you like. Then in your service, you can access them through OperationContext.Current.IncomingMessageProperties["RawMessage"].
We're consuming a web service (web reference, not service reference), and I need a way to output the entire message being sent (including headers) and the message that gets received.
When I add the web reference, the generated base type of the client object to send the messages is System.Web.Services.Protocols.SoapHttpClientProtocol
I send the messages like so:
ApiService api = new ApiService();
// set the certificate and basic http network credentials
var response = api.SendRequest(messageObject);
I'm able to get the body of the request by serializing messageObject, but can't figure out how to get the full message with the headers.
Since I'm using a certificate and basic authentication, tools like Fiddler, etc. aren't getting me what I need, so I believe I have do something programmatically to pull whats sent and whats received prior to being encrypted with ssl.
EDIT
What I want to see if the data being sent and received to another service from within my WCF service.... e.g.:
// this function is within my WCF service
public ResponseModel Auth()
{
// call to another service here... need to trace this
}
If this is for tracing purposes I have had some success using the tracing capabilities of the System.Net libraries, you should be able to enable the tracing through configuration only.
It's described here: How to: Configure Network Tracing
The resulting log file isn't the easiest to follow, but is described here: Interpreting Network Tracing
I am building a WCF based service application in .Net. I am currently designing the contracts.
Should I use response codes, exceptions or textual messages for my service responses to report service result status?
They will be consumed by web applications and other systems.
You should take a look at FaultContracts. See http://msdn.microsoft.com/en-us/library/system.servicemodel.faultcontractattribute.aspx
Your Fault Contract can include a (string based) error code for client side processing, and / or a textual message for display to users.
If your service, or rather you as a service designer, don't know what a (future) client application will want to do with an error message (display or process), include both.
In my opinion best is to use response enum (code) that make sense to client. Apart from it returning message may increase the dataload on the WCF service.
E.g.
throw new FaultException<InvalidArgumentException>(new InvalidArgumentException(),Constants.MaxLengthFields.PhoneNumber)), Response.OrderIdMissing);
[DataContract, Serializable]
enum Response
{
[EnumMember]
OrderIdMissing,
[EnumMember]
ProductCodeInvalid,
}
There are several articles available on the web. Please go though them for more concrete information.
http://blogs.msdn.com/b/brajens/archive/2007/04/23/exception-handling-in-wcf-web-service.aspx
http://blogit.create.pt/blogs/marcosilva/archive/2008/05/18/Developing-a-WCF-Service-%5F2D00%5F-Fault-Exceptions-AND-FAULT-Contracts.aspx
http://blogs.msdn.com/b/brajens/archive/2007/04/23/exception-handling-in-wcf-web-service.aspx