I am looking for a proper framework to implement the (web)service tier in .NET. I am a little bit familiar with WCF and wondering, if it can be customized the way I want it.
1)There is an industry standard for messages to be sent/recieved by the system, which defines the operations, types used, etc. It is XML based. It requires all requests/responses to be wrapped in an envelope, e.g.:
<xxx:Message>
<xxx:Header>
//some header data
</xxx:Header>
<xxx:Body>
<xxx:Command>
//request data
</xxx:Command>
<xxx:Command>
//request data
</xxx:Command>
<xxx:Body>
</xxx:Message>
The xxx:Command element actually identifies the operation to be performed and parameters, or contains the command execution result.
The WCF wraps everything to SOAP envelope. Can it be customized to send all requests using the envelope in the sample above, instead of SOAP? How should I code my services, so that all outgoing and incoming messages are parsed correctly. Should I look to [MessageContract] or [DataContract] attributes or both?
2)One-way operations. The industry standard states that the services should respond with the "acknowledgment" message, that the request has been received. I was looking at the one-way operations, that implement the similar approach - they notify the client as soon as the message is received by the server. I am wondering, how can I customize the "acknowledgment" message being sent to conform to the industry standard.
If WCF does not allow that, can you forward me to any other possible solution out there - Remoting, maybe some other web-services libraries?
1) Neither attribute will help you. Those attributes are interpreted by the binding (e.g., WS-HttpBinding) to determine how to actually create your messages. You're going to have to write a custom binding to do this, and possibly a custom serializer depending on how "request data" fields are structured.
2) Again, you're going to need to write a custom binding.
A quick search didn't show any existing implementations of a GSA S2S binding for WCF.
There are existing engines for S2S (for example S2SConnect). The licensing costs may or may not be worth the time savings from having to develop your own implementation.
Related
Please explain in detail. I have been telling my mentor that everything I've researched on WCF and many programmers all over the net say it is NOT good to pass DataSets to the service, why is that? I created a BUNCH of classes in the service and the work great with the application, but he says that I just wasted time doing all that work, he has a better way of doing it.
He keeps telling me to create a SINGLE OperationContract. There will be many functions in the service, but the OperationContract will take the string name of the function and the dataset providing the details for that function.
Is his way bad practice? Not safe? I'm just trying to understand why many people say don't use datasets.
The first reason is interoperability. If you expect consumers of your service to be implemented in any other technologies other than .NET, they may have lots of trouble extracting or generating the data in the DataSet, as they will have no equivalent data structure on their end.
Performance can be affected quite a bit, as well. In particular, the serialization format for untyped datasets can be huge because it will contain not just the data, but also the XSD schema for the data set, which can be quite large depending on the complexity of the DataSet. This can make your messages a lot larger, which will use more network bandwidth, take longer to transfer (particularly over high latency links), and will take more resources at the endpoint to parse.
So the web service you have does something specific lets say it sends a bunch of emails. Lets say this service has one method that sends an email. The method should accept and email address, subject and a body.
Now if we send a data set with the information required the service would have to know the shape of the data and parse it.
Alternatively if the web service accepted a object with properties for email address, subject and body. It can be used in more than one place and is less prone to going wrong dues to a malformed dataset.
One more thing: you can get incorrect data using DataSet.
For example a value in the DataSet might look like the following before serialization:
<date_time>12:19:38</date_time>
In the client it would come with a offset specified:
<date_time>12:19:38.0000000-04:00</date_time>
The client code would adjust this to its local time (much like Outlook when you schedule an appointment with someone in a different timezone).
More details can be found here.
Using WCF is not just an implementation decision - it is a design choice. When you choose to use WCF you have to abandon many of your treasured OO principles behind and embrace a new set of patterns and principals that are associated to service orientation.
One such principle is that of explicit contracts: A service should have well defined public contracts (see this Wikipedia article). This is crucial for interoperability, but is also important so clients have an accurate picture of what functionality your service provides.
A DataSet is basically just a big bag of "stuff" - there is no limitation to what it could contain - or any well defined contract that explains how I can get data out. By using a DataSet you introduce inherent coupling between the client and the server - the client has to have "inside information" about how the DataSet was created in order to get the data out. By introducing this level of coupling between the client and service you have just negated one of the main motivations for using WCF (precisely that of decoupling the two areas of functionality to allow for independent deployment and/or development lifecycle).
I'm currently implementing the publish-subscribe pattern for use in my future applications. Right now I'm having trouble figuring out the "best" way to design the message part of the pattern. I have a couple of ideas in mind but please tell me if there's a better way to do it.
Idea 1: Each message is an object that implements a simple tag interface IMessage.
Idea 2: Each message is represented as an array where the first index is the type of message and the second contains the payload.
Are any of these "better" than the other and if so, why? Please excuse me if this seems like a stupid question.
Your first idea make more sense, take a look at the NServiceBus github implementation of messaging patterns using marker interfaces or unobtrusive message definitions.
In essence a message in publish/subscribe scenario is an event, it's name should describe the event and have the relevant reference to data related to this event.
Andreas has a good article
HTH
Both approaches are useful. The first is useful when working with the message in your application. The second is useful if you are receiving raw message data over the network and have to determine how to deserialize it.
If you look at how WCF serializes, then they put the type as an attribute in the serialization, so it knows what to deserialize it to. However if you are going for JSON serialization fx, then you are probably better off having a property to hold your type information. Also be aware that this type information does not have to specify an actual CLR type, just an identifier to let you know how to read the data.
Once you know how to read the data, then you can create your object and take advantage of the type system, ex. using tag interfaces.
You don't specify whether your messages cross process boundaries or not.
In the latter case, where messages are passed between layers in the same application, the first approach where messages are just objects (optionally implementing the same interface) is probably the easiest.
In the former, where you have interprocess and interoperable messaging, I think you get the most of XML. XML is very flexible, easy to support in different techologies, allows you to sign messages in an interoperable way (XMLDSig) and allows you to create variety of different input/output ports (tcp/http/database/filesystem). Also, messages can be easily validated for their integrity with XSD specifications.
In the pypubsub library (a publish-subscribe for python), I found that there was great benefit to name the payload data, so the sender and receiver can just populate fields and not have to rely on order of items in message, plus it provides "code as documentation". For example, compare these, written in pseudocode. Using array:
function listener(Object[] message):
do stuff with message[0], message[1], ...
message = { 123, 'abc', obj1 } // an array
sendMessage('topicName', message)
Using keywords:
function listener(int radius, string username = None):
do stuff with radius, username, ...
// username is marked as optional for receiver but we override the default
sendMessage('topicName', radius=123, username='abc')
Doing this in C# may be more of a challenge than in Python, but that capability is really useful in pypubsub. Also, you can then use XML to define the schema for your messages, documenting the payload items, and you can mark some payload items as optional (when they have a default value) vs required (when they don't). The lib can also check that the listener adheres to the "payload contract", and that the sender is providing all data promised via the "contract".
You should probably take a look at (and even use) existing libraries to get some ideas (pypubsub is at pypubsub.sourceforge.net).
Both approaches are viable, the second one involves that you are responsible for the de/serialization of the message, it gives you much more freedom, power and control over the message, espacially versioning, but all this comes at a cost and I see this cost sustainable only if some of the actors are not .net actors. Otherwise go with the first approach and as Sean pointed out take a look at toolkits and frameworks that can greatly help you with all the plumbing.
I'm starting to experiment with using ActiveMQ (in conjunction with the ActiveMQ.NMS bindings) to support some cross platform RPC messaging that we're looking at doing.
As part of this I'd like to be able to define our RPC contracts in the manner WCF provides - eg.
[ServiceContract]
public interface IUsers
{
[OperationContract]
IEnumerable<IUser> void GetByEmail(string email);
}
And I'm looking at contributing to the ApackeMQ.NMS.WCF project to allow this to work, and I have some experience at writing custom bindings so I'm away with that.
However, I'm having trouble with a conceptual issue first with how WCF operates. Obviously at some level a call through a proxy on a client channel for "GetByEmail" must get converted into message and response objects so that they can be serialized. I'd like to be able to know how this works to get a better overall understanding of WCF.
I am unable to find any documentation as to exactly how that is done and indeed which classes within the fairly hefty WCF infrastructure are involved.
Has anyone got any pointers? A top level explanation and/or directions to the classes would be brilliant.
Thanks.
There is a step before that: How (what format) to use for the serialization?
WCF connects through Bindings, and the configuration of the binding picks a format/protocol.
And 'how' the command is transferred for each protocol? I don't know and I don't think it will be very helpful to dig into that (low level) stuff.
I'm pulling together some services in C# that have to match specific data format; e.g. string lengths, various enumerations and formatting. I have the back-up approach to validate post the SOAP call and respond with friendly messages and pre-defined error codes, but I would like to place additional information into the WDSL (so it is clear that field x can only be 15 alpha characters only with no numbers or punctuation for example).
Is this possible, if so are there any examples and or tutorials?
Take a SOAP message, generate a XSD out of it, and then edit the XSD until all your validation things are in there. Provide the XSD along with the WSDL to your customer.
When you both validate the messages using the same XSD the problem should be gone.
First of all, you should be aware that .NET does not validate SOAP messages against the schema in a WSDL. For instance, if part of your input message shows a maxLength of 50, there will be no error or exception when you are sent 51 instead.
Second, it is not possible to adjust your classes in such a way that you can control the exact schema. For instance, you cannot cause a maxLength attribute into the WSDL.
Third, if you must completely control the WSDL, then you need to write it by hand. You will never have complete control over the WSDL that .NET generates.
Finally, you seen to be talking about ASMX web services here. You should not be using ASMX web services for new development - they have been replaced with WCF.
My company is developing an application that receives data from another company via TCP sockets and xml messages. This is delivered to a single gateway application which then broadcasts it to multiple copies of the same internal application on various machines in our organisation.
WCF was chosen as the technology to handle the internal communications (internally bi-directional). The developers considered two methods.
Individual methods exposed by the
WCF service for each different
message received by the gateway
application. The gateway
application would parse the incoming
external message and call the
appropriate WCF service method. The
incoming XML would be translated
into DataContract DTO’s and supplied
as argument to the appropriate WCF
method.
The internal application
exposed a WCF service with one
method “ProcessMessage” which
accepted an Xml string message as
argument. The internal app would
parse then deserialize the received
xml and process it accordingly.
The lead developer thought option two was the better option as it was “easier” to serialized/deserialize the xml. I thought the argument didn’t make sense because DataContracts are serialized and deserialized by WCF and by using WCF we had better typing of our data. In option 2 someone could call the WCF service and pass in any string. I believe option 1 presents a neater interface and makes the application more maintainable and useable.
Both options would still require parsing and validation of the original xml string at some point, so it may also be a question where is the recommended place to perform this validation.
I was wondering what the current thoughts are for passing this kind of information and what people’s opinions on both alternatives are.
Option 1 is suited if you can ensure that the client always sends serialized representations of data contracts to the server.
However if you need some flexibility in the serialization/deserialization logic and not get tightly coupled with DataContracts, then option 2 looks good. Particularly useful when you want to support alternate forms of xml (say Atom representations, raw xml in custom format etc)
Also in option 2 inside the ProcessMessage() method, you have the option of deciding whether or not to deserialize the incoming xml payload (based on request headers or something that is specific to your application).
In option 1, the WCF runtime will always deserialize the payload.
I recently asked a couple of questions around this area: XML vs Objects and XML vs Objects #2. You'll find the answers to those questions interesting.
For our particular problem we've decided on a hybrod approach, with the interface looking something like this:
// Just using fields for simplicity and no attributes shown.
interface WCFDataContract
{
// Header details
public int id;
public int version;
public DateTime writeDateTime;
public string xmlBlob;
// Footer details
public int anotherBitOfInformation;
public string andSoemMoreInfo;
public book andABooleanJustInCase;
}
The reason we use an xmlBlob is because we own the header and footer schema but not the blob in the middle. Also, we don't really have to process that blob, rather we just pass it to another library (created by another department). The other library returns us more strongly typed data.
Good luck - I know from experience that your option 2 can be quite seductive and can sometimes be hard to argue against without being accused of being overly pure and not pragmatic enough ;)
I hope I understood this right. I think it might make sense to have your gateway app handle all the deserialization and have your internal app expose WCF services that take actual DataContract objects.
This way, your deserialization of the TCP-based XML is more centralized at the gateway, and your internal apps don't need to worry about it, they just need to expose whatever WCF services make sense, and can deal with actual objects.
If you force the internal apps to do the deserialization, you might end up with more maintenance if the format changes or whatever.
So I think I would say option 1 (unless I misunderstood).