views:

41

answers:

3

I have a service method with a couple of parameters that will be always provided and additional parameters that will change by names and number of parameters (I will know which parameters to expect by the ACTION field)

To solve a design problem like the above I created a web service with the parameters that will be always provided and one more parameter that will accept a string that is written in a Key<*>value way.

using MyServiceMethod:

Action : Action1
Param2: Hello
param3: world
Additional_Params: name<*>Jack;address<*>2 street;

(I know that with Action1 I get a Name and address values from the person who uses the service)

using MyServiceMethod for the second time:

Action : Action5
Param2: Hello
param3: world
Additional_Params: numOfHours<*>3;Sum<*>342;myName<*>asaf;

I think this is not the best design for a web service that accept a different data with each ACTION, is there a better way to do that ?

+2  A: 

If you have a small set of actions, it would probably be the best design strategy to simply use a single method for each action. It probably won't require as much work to pick apart on the back end and, in my opinion, there's no shame in it.

If you have a large set of actions, you may be able to represent what you want to do as a data structure, and pass only that parameter in.

I wouldn't say the way you're proposing to do it is wrong, anyway, but it may actually end up creating more work for you and being confusing to you or another developer later.

Eugarps
The issue isn't just how large the set is, but how variable. If it never changes, then even having a large number of functions would be fine.
Steven Sudit
+2  A: 

I'm not 100% clear on what you're trying to do, but if you know that Action1 will always be called with the name/value pairs of "name" and "address", and Action5 will be called with "numOfHours", "Sum" and "myName", then I agree with @Eugarps answer and @Steven_Sudit associated comment. Simply expose them as parameters on the method for each action.

If however, you don't know what the variable parameters are going to be (only that you will get certain name/value pairs when invoking the actions), then I would at least use an IDictionary<string, object> rather than a string. Doing it this way means that you can avoid parsing string values. If the values being passed are instances of your own types (rather than primitives), then you'll also need to make use of the ServiceKnownType attribute to tell the serializer about them.

Tim Roberts
Another way to go is to change the interface to accept a XML document, which itself may be the serialization of a DTO.
Steven Sudit
i think an XML solution will cause a very large chunk of code to verify the XML structure (xsd) and analyze the XML.... i don't know....
Rodniko
can i pass IDictionary in GET url?
Rodniko
How is the client going to be calling your services? It sounds like you might be trying to do REST. I've not done anything with REST so I'm not sure about how to pass Dictionaries with it. You can definately use Dictionary and Dictionary<K,V> with WCF though.
Tim Roberts
A: 

I've kind of already answered in comments, but here it is in one place:

If you have a small number of different functions, which change rarely, the best way is just to expose each as a separate function. When new ones are needed, you can extend your interface without breaking existing code.

Now, on the other hand, if you had a larger number of functions and/or they changed frequently, then a simple but flexible interface would be better. You could have a single function exposed, taking an XML document that is a serialization of a request DTO. This will require some demux logic (switch/case or, better, a lookup table of delegates) to dispatch the requests to a handler. This approach is harder to get going, but easier to maintain.

Steven Sudit