PDA

View Full Version : WebServiceExporter id and target name


EJS
10-20-2006, 04:23 PM
Hi all,

I had trouble getting the WebServiceExporter to work properly. I had built my service to the example of the BookingAgent, but when entering the service url in the browser I got:
"This web service does not conform to WS-I Basic Profile v1.1."

Then I found out that I had been calling the target name of the WebServiceExporter, instead of the id of the WebServiceExporter, like so:
http://localhost/springair/BookingAgent.asmx
instead of
http://localhost/springair/BookingAgentWebService.asmx

Of course, when calling the target, the type configured for that id gets exported, and it does not have any WebService or WebMethod attributes...hence the message...

Is there any way to prevent a call to the target from resulting in the message stated above? Or shouldn't we bother?

Cheers,
EJ

Bruno Baia
10-22-2006, 10:53 PM
Hi,

Thanks for reporting this.
We need to do something here.. as you pointed out, every object registered with Spring can be called as a web service calling <ObjectId>.asmx

We can detect if the Object Id refers to a WebServiceExporter, or if the type is decored with a WebServiceAttribute, because the WebServiceExporter is not necessary when the service is already decorated with the needed attributes :


namespace MyComany.MyApp.Services
{
[WebService(Namespace="http://myCompany/services")]
public class HelloWorldService
{
[WebMethod]
public string HelloWorld()
{
return "Hello World!";
}
}
}


<object id="HelloWorldService" type="MyComany.MyApp.Services.HelloWorldService, MyComany.MyApp" />

The web service works and is avalaible @ MyApp/HelloWorldService.asmx


I've created an issue in JIRA (http://opensource.atlassian.com/projects/spring/browse/SPRNET-377).
I think WebServiceHandlerFactory will be affected.


Cheers,
Bruno

Aleks Seovic
10-23-2006, 12:41 PM
Yeah, this is probably a good idea.

All that we need to do is check whether specified object definition's type has WebServiceAttribute, and throw a more meaningful exception if it doesn't. Shouldn't be very difficult...

- Aleks

Mark Pollack
10-23-2006, 05:41 PM
Hi,
We should try to provider a better error/info message for this case if we can - as it can be confusing at first what name to use in the url. The implementation suggested would have to change if we wanted to add/override existing web method attributes (or others) already defined on a class. What does everyone think about such a feature?
Mark

BTW, I think we can provide some generic functionality for the exporter such that we can define things like


<property name="MethodAttributes">
<dictionary>
<entry key="FindAll" value="WebMethod(Description = 'Test', TransactionOption = TransactionOption.RequiresNew ), SoapDocumentMethod(Action="urn:myservice:finall")
"/>
</dictionary>
</property>


I'm sure it can be cleaned up even more XML wise, but using the expression evaluator and a simple parser for the value, we could probably implement this and then not be in a catchup game to regardnig all the attributes that can be used. This should be generally useful for WCF, EnterpriseServices, etc.. I'll post on the dev list - just wanted to get it out there.

Bruno Baia
10-24-2006, 05:02 AM
Hi,
We should try to provider a better error/info message for this case if we can - as it can be confusing at first what name to use in the url. The implementation suggested would have to change if we wanted to add/override existing web method attributes (or others) already defined on a class. What does everyone think about such a feature?
Mark

BTW, I think we can provide some generic functionality for the exporter such that we can define things like


<property name="MethodAttributes">
<dictionary>
<entry key="FindAll" value="WebMethod(Description = 'Test', TransactionOption = TransactionOption.RequiresNew ), SoapDocumentMethod(Action="urn:myservice:finall")
"/>
</dictionary>
</property>


I'm sure it can be cleaned up even more XML wise, but using the expression evaluator and a simple parser for the value, we could probably implement this and then not be in a catchup game to regardnig all the attributes that can be used. This should be generally useful for WCF, EnterpriseServices, etc.. I'll post on the dev list - just wanted to get it out there.

Hi Mark,

we can already do that (see SpringAir example) :

<!-- Web service definitions -->
<object id="bookingAgentWebService" type="Spring.Web.Services.WebServiceExporter, Spring.Web">
<property name="TargetName" value="bookingAgent"/>
<property name="Name" value="BookingAgent"/>
<property name="Namespace" value="http://SpringAir/WebServices"/>
<property name="Description" value="SpringAir Booking Agent Web Service"/>
<property name="Methods">
<dictionary>
<entry key="SuggestFlights">
<object type="System.Web.Services.WebMethodAttribute, System.Web.Services">
<property name="Description" value="Gets those flight suggestions that are applicable for the supplied trip."/>
</object>
</entry>
<entry key="Book">
<object type="System.Web.Services.WebMethodAttribute, System.Web.Services">
<property name="Description" value="Goes ahead and actually books what up until this point has been a transient reservation."/>
</object>
</entry>
<entry key="GetAirportList">
<object type="System.Web.Services.WebMethodAttribute, System.Web.Services">
<property name="Description" value="Return a collection of all those airports that can be used for the purposes of booking."/>
</object>
</entry>
</dictionary>
</property>
</object>


But as you pointed out, we can make configuration less verbose and easier to read.
I was thinking to xsd schema configuration parser for that, we should get something like this :

<ws:exporter name="bookingAgentWebService" targetName="bookingAgent"
namespace="http://SpringAir/WebServices"
description="SpringAir Booking Agent Web Service">
<methods>
<entry key="SuggestFlights">
<ws:webMethod Description="Gets those flight suggestions that are applicable for the supplied trip."/>
</entry>
<entry key="Book">
<ws:webMethod Description="Goes ahead and actually books what up until this point has been a transient reservation."/>
</entry>
<entry key="GetAirportList">
<ws:webMethod Description="Return a collection of all those airports that can be used for the purposes of booking."/>
</entry>
</methods>
</ws:exporter>

Or with your example :

<entry key="FindAll">
<ws:webMethod Description="Test" TransactionOption="RequiresNew" />
<ws:soapDocumentMethod Action="urn:myservice:finall" />
</entry>


- Bruno

Bruno Baia
10-24-2006, 05:23 AM
Yeah, this is probably a good idea.

All that we need to do is check whether specified object definition's type has WebServiceAttribute, and throw a more meaningful exception if it doesn't. Shouldn't be very difficult...

- Aleks

Hi,

I've commited a fix where I just let the default implementation take care of this when the object does not define a Web Service.
So we'll have "Page resource not found" error in this case (404), I know it will not help the user but who knows if there aren't any asmx files with the name of an existing spring object...

Another point is that the WebServiceAttribute is only optional, it does not have an impact when using WebServiceExporter, but it does with the different approach I got in the previous post (HelloWorldService example).
It's not the recommended way to export a Web service and I would not have to even speak about it...


Bruno

Mark Pollack
10-24-2006, 06:57 PM
Hi,
I know what we can do now - which is limited to only the web method attribute and doesn't allow for overriding/merging if the target class already contains the attribute. What I was getting at was to avoid having to write the schema for every possible attribute that maybe out there and support for overriding/merging. Using the expression evaluator can help out implementation wise. I was picturing something like this...

<entrykey="FindAll">
<list>
<value>WebMethod(Description = 'Test', TransactionOption = TransactionOption.RequiresNew )</value>
<value>SoapDocumentMethod(Action='urn:myservice:final=')</value>
</list>
</entry>


We would define type aliases/type converters for common cases.
Mark

Bruno Baia
10-24-2006, 11:05 PM
which is limited to only the web method attribute and doesn't allow for overriding/merging if the target class already contains the attribute.
As a note, different attributes are supported now in WebServiceExporter (using a List). Same for overriding.
Merging (if we did it) will not be easy to implement and will depend how we'll define the attribute (xsd schema, expression, etc..)

- Bruno

Mark Pollack
10-25-2006, 04:04 PM
Hi,
My bad about only supporting WebMethod... I tried overriding but it didn't work. I'll check again. The merging doesn't seem to bad to me since the syntax in C# for attributes is pretty easy to parse out and then pass on to the expression evaluator. I was generally hoping to get to a cut-n-paste style, i.e. cut from C# into XML, in order to give a familiar syntax and to cut down on the verbosity of the xml. Lets move this onto the dev list and I'll try to clarify/propose some things.
Mark

Bruno Baia
10-27-2006, 11:53 AM
EJ,

Give a try to the latest nightly build and let us know if it works.

- Bruno

EJS
10-27-2006, 02:11 PM
Hi Bruno,

Just downloaded the latest build and yes, it works. I now get a 'decent' 404, so to speak.

Thanks a lot,
EJ