I have a preliminary specification for an application that consumes a web service by doing the following... 1. creates a proxy of the web service 2. creates a request object "A" that inherits a base request class and populates these properties accordingly 3. creates another request object "B" (identical to the first request object) to pass the returning object into 4. makes the web method call passing in "A" into the web method associated with the proxy and tosses that return into "B" The problem is it also references a base response object in the spec but doesn't give a lot of detail on how that should be implemented. Now granted its a preliminary spec that I am playing with but it begs a best practice question on how base response and base request objects in web method calls are typically used.
My own experience has typically been as follows... 1. creates a proxy of the web service 2. creates a request object "A" that inherits a base request class and populates these properties accordingly. 3. create a response object "B" that inherits a base response class. 4. make the web method call passing in "A" into the web method associated with the proxy and tosses that return into "B"
Given the first example the request object can't really inherit both base classes unless it was somehow sequential (i.e. baseRequest inherits baseResponse and then request inherits baseRequest) or you could include properties for request and response data in the same base class and it would subsequently only need to inherit the same base class. Both of those are counter to what I have seen and used in the past. Question is what are the pros and cons for either of these approachs. I would like to hear from the C# community if there might be a best practice in this regard I may be overlooking here. Any and all input would be appreciated. thanks, Matt - Edited bymathiasX Thursday, September 10, 2009 4:25 PMI guess I wasn't clear initially on what I meant.
- Moved bynobugzMVP, ModeratorThursday, September 10, 2009 12:20 AM (From:Visual C# General)
-
| | mathiasX | I can't recall that I've seen a web service that had base request and response objects at all. In fact, many don't have "request objects" in the sense of an object intended to hold the parameters of the request.
John Saunders
WCF is Web Services. They are not two separate things.
Use WCF for All New Web Service Development, instead of legacy ASMX or obsolete WSE
Use File->New Project to create Web Service Projects
| | John Saunders | Sorry if I was sort of confusing in my original post. The application I am talking about consumes a web service. It is not a web service itself. It has several web methods it would use from the web service all of which have some common request properties that need to be passed in as well as common response properties that would be returned. With that distinction now reiterated, is this still the correct forum for my inquiry? | | mathiasX | You should really use WCF ("Add Service Reference") for your client. In that case, the forum you should post to is http://social.msdn.microsoft.com/forums/en-US/wcf/threads/. If you are using ASMX ("Add Web Reference"), then this is the correct forum. In either case, you should give an example of the kind of thing you're talking about.
John Saunders
WCF is Web Services. They are not two separate things.
Use WCF for All New Web Service Development, instead of legacy ASMX or obsolete WSE
Use File->New Project to create Web Service Projects
| | John Saunders | Unfortunately it's not my call on what type (wcfor asmx)the web service will be. I just have to consume it with my app. In either case you create a proxy of the service and then we are right back to... 1. creates a proxy of the web service...etc
Let me try and rephrase this. I have an application that needs to consume a web service (lets ignore what the service type is for now). In this same application I will have a "Request" classthat includes properties and collections that when instantiated and populated accordingly, will need to be passed into the web method call. In this same application I will have a "baseRequest" base class with common request properties and a "baseResponse" base class with common response properties. I will also have a "Response" class that when instantiated will be the object that my return will be passed into. The Request class will inherit from the "baseRequest" class and the Response class will inherit from the baseResponse class as follows...
class Request : baseRequest {...} class Response : baseResponse {...}
I create the proxy (or client) and pass the request object into the service method
client = new SomeWebService.Service1(); myResponse = client.SomeWebMethod(myRequest);
and pass the return into an instantiated Response object. This is how I would normally pass complex objects (that include collections)into a web service method and return them as well. In this case the request object passed is distinctly different from the response object returned, ergo the two seprate classes.
My original preliminary spec says the object I am passing into the web service methodshould bethe same type of object that my return should be passed into. In essense I am passing in a Request object and returning it into a Request object as well. This same dcocument makes reference to base request properties and base response properties. If we have base response and base request properties and need to incorporate them into the single Request class, you can only inherit one base class as follows...
class Request : baseRequest {...} or class Request : baseResponse {...}
So as far as I can see that leaves you with the option of layering the inheritance (probably not the correct terminology) as follows...
class baseRequest : baseResponse {...} class Request : baseRequest {...}
or coming up with a single class that incorporates both base request and base response properties in the same class as follows...
class baseReqResp {//both sets of properties here...} class Request : baseReqResp {...}
Given these two alternatives, which is the better approach or is there another I may not have thought of. Or should I be pushing back and advocating thatwe have seperateRequest and Response classes as outlined in my fiirst scenario [and yes also advocating WCF ;) ]
I hope this maybe makes things a little clearer and I welcome any and all adviceonthis. I still have a lot to learn in this area. Thanks, Matt
- Edited bymathiasX Thursday, September 10, 2009 9:53 PMSpelling
-
| | mathiasX | I know you're trying to consume the service. That's why I suggested that you use "Add Service Reference" to create a WCF client, instead of "Add Web Reference", which creates an ASMX client.
John Saunders
WCF is Web Services. They are not two separate things.
Use WCF for All New Web Service Development, instead of legacy ASMX or obsolete WSE
Use File->New Project to create Web Service Projects
| | John Saunders | It makes it clearer, though I can't see why you'd design it this way. When I say that I've never seen it done this way, that was a nice way of saying that I question your design. Rather than architecting request and response classes ahead of time, simply allow each operation to accept whatever it needs, and to return whatever it wants. If it turns out that the request and response messages are clearly hierarchical, then you'll have your original design. I think it's unlikely to turn out that way. You're looking for multiple inheritance. Neither .NET nor web services support multiple inheritance.
John Saunders
WCF is Web Services. They are not two separate things.
Use WCF for All New Web Service Development, instead of legacy ASMX or obsolete WSE
Use File->New Project to create Web Service Projects
| | John Saunders | This must not be my day for communication skills or I just don't get it. Both being very likely candidates since I am still somewhat new to some of this. When you say "simply allow each operation to accept whatever it needs, and to return whatever it wants" I guess I don't quite understand what the implementation of this looks like. I have some banking transactions that include customer account information along with an indeterminatenumber of transactions in a generic collection (and some other supporting collectionsof data that may or may not be requireddepending on the customer) that need to be passed into the web service. The number of transactions could be from0to 5, but each transaction has its own set of properties that will be populated and then passed into the web service call. When I referred to "includes properties and collections" thats what I meant. When you refer to "each operation" I am assuming you mean the particular web method I would be passing this data into? Aside from creating an object that can hold all of this data needed by the web service to fulfill its function, how else would you pass all of this into the web method? Unless I am mistaken each web method in the web service needs to declare what the input parameters are so that might make for quite a few overloaded web methods on the web service side, wouldn't it? Wouldn't it be better to create a class that captures all this data into an object and then passes that object into the web method call? Does what I just described meet your definition hierarchical? If it doesn't then please clarify for me what you meant by that. When I said "you can only inherit one base class" I thought I was acknowledging the fact that multiple inheritance in not possible. The example I cited of...
class baseRequest : baseResponse {...} class Request : baseRequest {...}
isn't multiple inheritance and works fine. It may not be a good idea but it at least leads back to the original question I asked. But it sounds like I have bigger problems with how I am trying to structure my data to be consumed by the web service. Seems to be some point here that I am missing so please take the time to straighten me out on this. Thanks for your patience and help, Matt | | mathiasX | Yes, I'd use an object for each web method, and each would return an object. But each request object would only contain the properties and collections that is required by the particular web method. Each response would contain only the properties required to be returned. Is it really the case that all (or most) of your web methods accept this same common structure of customer account info followed by 0 to five transactions? Also, did I understand you correctly that you have a requirement for the response to include the request? In that case, I might do something like this for the objects that are in common:
public class TransactionRequest
{
private List<TransactionBase> _transactions =
new List<TransactionBase>(5);
public CustomerAccountInfo Account {get;set;}
public List<TransactionBase> Transactions
{
get {return _transactions;}
}
}
public enum TransactionStatusCode {Success, Failure}
public class TransactionResponse
{
public TransactionStatusCode Status {get;set}
public string StatusMessage {get;set;}
public TransactionRequest OriginalRequest {get;set;}
}
[WebMethod]
public TransactionResponse DoTransaction(TransactionRequest request)
{
return new TransactionResponse
{
Status = Failure,
Message = "Not yet implemented",
OriginalRequest = request
};
}
John Saunders
WCF is Web Services. They are not two separate things.
Use WCF for All New Web Service Development, instead of legacy ASMX or obsolete WSE
Use File->New Project to create Web Service Projects
- Unproposed As Answer bymathiasX Tuesday, September 15, 2009 10:07 PM
- Proposed As Answer bySteve MaineMSFT, ModeratorFriday, September 11, 2009 8:37 PM
-
| | John Saunders | No, notall of the web methods for this particular web service require a set of properties and collections with an indeterminate number of elements, in fact most don't. Aside from the few complex ones, the rest are in fact are pretty straight forward. The ones I am more concerned about are the complex ones.However,they all require a base set of request properties passed in. Thats why the reference to a base request class so I can abstract that data and any request object created can inherit this set of properties.The sameis truefor the response as well.
With regard to the request data being passed back,that is dictated by the factthat the I have to pass thereturn data into the exactsame type of object as theoriginal request object as follows...
public class BaseResponse {...}
public class BaseRequest : BaseResponse {...}
public class TransactionRequest : BaseRequest {...}
... TransactionRequest myRequest = new TransactionRequest(); TransactionRequest myResponse = new TransactionRequest(); client = new SomeWebService.Service1(); myResponse = client.SomeWebMethod(myRequest); ...
[WebMethod] public TransactionRequest DoTransaction(TransactionRequest request) { //some stuff gets done that populates the response properties of the object passed in...
return request }
I understand the reluctance to create a request object that inherits response properties that aren't populated when passed into the web method. The crux of the problem as stated earlier is the need to use the same type of object for a request object as I do for a return object (not my preference but thats the way it is). I have to have response properties returned that will drop into the same type of object and I can't think of any other way around this issue than to create these place holder response properties in the original request object. That way the request object passed in will have request property data in place with no response data, but when it is returned it would return the exact same object but with the response data in place. This would allow me to use the same type object to return the data into.
Probably not the best way to do things, I know, but given the constraints I am operating under this is the best I have been able to come up with so far. If you can think of another more efficient way of doing this please let me know.
| | mathiasX |
|