Why does tempuri.org exist? Why does each XML Webservice require its own namespace, unique from any other on the web?
Unfortunately the tempuri.org URL now just redirects to Bing.
You can see what it used to render via archive.org:
https://web.archive.org/web/20090304024056/http://tempuri.org/
To quote:
Each XML Web Service needs a unique namespace in order for client
applications to distinguish it from other services on the Web. By
default, ASP.Net Web Services use http://tempuri.org/ for this
purpose. While this suitable for XML Web Services under development,
published services should use a unique, permanent namespace.
Your XML Web Service should be identified by a namespace that you
control. For example, you can use your company's Internet domain name
as part of the namespace. Although many namespaces look like URLs,
they need not point to actual resources on the Web.
For XML Web Services creating[sic] using ASP.NET, the default namespace can
be changed using the WebService attribute's Namespace property. The
WebService attribute is applied to the class that contains the XML Web
Service methods. Below is a code example that sets the namespace to
"http://microsoft.com/webservices/":
C#
[WebService(Namespace="http://microsoft.com/webservices/")]
public class MyWebService {
// implementation
}
Visual Basic.NET
<WebService(Namespace:="http://microsoft.com/webservices/")> Public Class MyWebService
' implementation
End Class
Visual J#.NET
/**#attribute WebService(Namespace="http://microsoft.com/webservices/")*/
public class MyWebService {
// implementation
}
It's also worth reading section 'A 1.3 Generating URIs' at:
http://www.w3.org/TR/wsdl#_Toc492291092
Webservices require unique namespaces so they don't confuse each others schemas and whatever with each other. A URL (domain, subdomain, subsubdomain, etc) is a clever identifier as it's "guaranteed" to be unique, and in most circumstances you've already got one.
http://en.wikipedia.org/wiki/Tempuri
tempuri.org is the default namespace URI used by Microsoft development products, like Visual Studio.
Probably to guarantee that public webservices will be unique.
It always makes me think of delicious deep fried treats...
Note that namespaces that are in the format of a valid Web URL don't necessarily need to be dereferenced i.e. you don't need to serve actual content at that URL. All that matters is that the namespace is globally unique.
Related
I know how mythz generally feels about HATEOAS, but let's say that I have to follow the HATEOAS principles in my REST services and add links ("self", "parent", and other possible relations) to my DTOs.
Links like "self" and "parent" contains paths to the resources and those paths are of course related to my routes.
I'm using the following project/deployment structure for my ServiceStack REST service. If that matters, I'm using ServiceStack 3.9.71.
Service Gateway Assembly:
defines my DTOs. Each DTO has a factory creating that DTO from the corresponding domain object
defines operations and their routes
Service Implementation Assembly:
uses ServiceGateway to get DTO definitions and access their factories
does whatever domain logic requires and create the corresponding DTOs through the afore mentioned factories
Service Interface Assembly:
define my REST services and
calls ServiceImplementation from ServiceStack's HttpHandler, according to REST verbs (GET, POST, ...)
WHERE would be the proper place to add link information to my DTOs?
Option1:
In my Service Gateway, when I build the DTOs themselves. It seems logical:
I know what I need to know about my domain objects and I can easily
build the links. Except that my DTOs are now all including an
additional member (Links) and building those links forces me to
explicitly provide paths/routes (i.e. hard code them). Seems to lead
to a maintenance nightmare.
Option2:
In my Service Interface assembly, where I have the request context and
I know my routes. I can encapsulate whatever my Service Implementation
returns in a meta-object containing the response and a link
collection. However, to build that link collection, I sometimes need
information available at the domain (i.e. Service Implementation)
level. The big "con" side for me is that it creates a new additional
and artificial level in all my responses. Could be seen as a way to
standardize response formats but I don't like it.
Option3:
My hope is that I can write a wrapper generically "injecting" a "Links" member to all the DTOs
I return by hooking somewhere into ServiceStack in my Service Interface assembly. I haven't
investigated much in that direction because I feel I could be wrong on
the whole approach here.
Any advise / suggestion welcome. Thanks to all.
I'm not sure If I'm suggesting you option1 or option3, but this Is what I came out after trying to do the same thing.
I started from this answer.
Now you can access route metadata directly from filters.
So my current approach is:
=> Services create the dto responses and the next collection of hypermedia links that will be attached to the response. In this level you know the "operations" by type but not "how" you will build the routes. I think it is coherent that domain level deals with workflows of operations.
=> Within a response filter I get the available routes from Metadata, and build the routes from dto properties by convention. Finally routes are added to http header.
Caveats:
I'm mapping 1 dto - 1 route. This approach could be more difficult in other cases.
Registering filters with whiteboard.
Hi,
I'm trying to use a Servlet filter with a servlet. I'm using Pax-Web 3.0, Declarative services and whiteboard.
I have to declarative service components (one for the servlet and one for the filter), and it seems to work fine.
Looking at the documentation I see the following sentence:
For URL Patterns, the pattern registered must be already mapped,
either as Resource or a Servlet alias - e.g there should already be a
Resource or aServlet registered to the path /foo. For Servlet names,
the names used should have been the name that has been explicitly
given to the Servlet (as servlet-name), when registering.
How can I guarantee that in a whiteboard setting? I have no idea when the servlet actually gets registered. I guess I can list the servlet as a dependency of the filter, but that makes it tricky to use the filter for multiple servlets.
Is there a better way?
regards, Frank
It seems highly unlikely that this is an issue. I expect that the sentence from the documentation indicates that your filter just never get called when there is no destination for the path. I.e. the filter is only called when there is a valid destination (a resource or servlet). A basic aspect of the whiteboard is that you should not care about these issues. It is the responsibility for the whiteboard to handle the http service, the filters, and the servlets in any possible registration order. If not ... it needs a serious issue raised.
I have not looked at the code but I am a heavy user of the whiteboard + filter + servlet + DS and never have seen an issue.
How to call webservice programmatically in asp.net without using add web reference?
My webservice url keeps on changing. Hence i need to capture the url at runtime and display the results.
Please advice.
You can change the URL of a web-reference at runtime (provided that the new address is hosting a service with the same schema that you originally used to create the reference):
MyWebService ms = new MyWebService();
ms.Url = "http://example.com/webservice.asmx";
ms.MyWebMethod();
Web References are definitely the way to go - whilst the classes that are created by the web reference are usually pretty heavy, all that strong typing makes it well worth your while.
you need to do the following steps.
PreReq :
First of all, you know the URL of web service.
Solution:
use wsdl.exe to create a proxy class and than compile it.
wsdl /out:myProxyClass.cs http://hostServer/WebserviceRoot/WebServiceName.asmx?WSDL
(there are other switches available
for wsdl. For Example to generate VB
class, you need to add switch
/language:VB)
Once your proxy class is generated you can easily consume in code.
MyProxyClass objService = new MyProxyClass();
DateTime time = objService.GetServerTime(); //Suppose service has method getServerTime
You can specify the end-point URL as part of the constructor of your client-side proxy class.
If you don't need to specify it during runtime then it can also be set in your web.config file.
Where are you trying to call the service and where the service file is located?
If the service is located on the same site. Why not just instantiate the class name from the service. Or just create a separate class and use interface
I have a web service in Grails, published using the xfire plugin. It's all fine and can be connected to no problem at all. But I'd like to modify the format of the request and response. Is that possible?
The example structure is:
Domain class Person, has many Siblings. Each Sibling has a Child.
My web serice method currently looks something like this:
Person updatePerson(Person person) {
return Person.getById(person.id)
}
But that produces a WSDL with the format:
Person
Person fields
Sibling
Sibling fields
Child
Sibling
Sibling fields
etc etc.
I don't want to accept the data in this format, or return it in that format. Is there a way of specifying which fields are exposed to the web service and what the WSDL should look like, or is xfire the wrong plugin to use for this?
I would answer this as its creator.
To exclude some domain properties, add:
static xmlTransients = ['your_property_goes_here']
to your domain classes.
However, the plugin does not allow you to control creation of the WSDL directly.
I would recommend looking at the Spring WS plugin. It's designed around "contract-first" web service development, so you have complete control over the resulting WSDL. The Xfire, Axis and Metro plugins are all great, but from my experience are all geared towards code-first and don't allow direct control over the resulting interface/output.
Preface
We are providing customers with our service API.
Each customer has own subdomain (e.g. sergii.ourwebsite.com) and own WSDL URL, it looks like http://sergii.ourwebsite.com/api/bsapi.cfc?wsdl
Also, all the websites (including API, of course) using the same codebase.
Problem
Say, two applications on same CF-server. This can easily happen, because some of customer websites are hosted on our servers.
Both trying to use own API WSDL, say:
http://sergii.ourwebsite.com/api/bsapi.cfc?wsdl
http://galashyn.ourwebsite.com/api/bsapi.cfc?wsdl
And here come the problems.
When second website tries to register the web-service, CF throws an error:
Name:
https://galashyn.ourwebsite.com/api/bsapi.cfc?wsdl.
WSDL:
https://galashyn.ourwebsite.com/api/bsapi.cfc?wsdl.
org.apache.axis.wsdl.toJava.DuplicateFileException:
Duplicate file name:
/opt/coldfusion8/stubs/WS1985941973/api/Bsapi.java.
Hint: you may have mapped two
namespaces with elements of the same
name to the same package name. It is
recommended that you use a web browser
to retrieve and examine the requested
WSDL document to ensure it is correct.
If the requested WSDL document cannot
be retrieved or is dynamically
generated, it is likely that the
target web service has programming
errors.
Problem is that both of them are using same WSDL namespace, built from CFC path:
<wsdl:definitions targetNamespace="http://api">
Current solution
The only working solution for us is using the CFC aliases, like:
http://galashyn.ourwebsite.com/api/v1n1/bsapi.cfc?wsdl
http://galashyn.ourwebsite.com/api/v1n1/bsapi.cfc?wsdl
Each this CFC extends the parent like this:
<cfcomponent output="false" extends="api.bsapi">
<!--- this component used to extend base api version 1.x --->
</cfcomponent>
They produce different namespaces, which can be used without problems -- own namespace for each application:
<wsdl:definitions targetNamespace="http://v1n1.api">
<wsdl:definitions targetNamespace="http://v1n2.api">
This is pretty dumb workaround, but it works for now.
Other solution would be to use the single API sub-domain and identifying the customers by some key (we are already using them for security purposes), but it has serious negative problems for us because of some legacy code.
Please note that I don't know Java, so many specific advices are not so clear for me.
Google shows that this problem exists for years, but I can't find the smart solution.
So maybe here?
I can not "place the WSDL at a common URL for all customers" for now and I've explained why: because I have to use the sub-domains. If you know the way to put the WSDL at one URL and make service requests to another -- please tell me.
A WSDL is just an XML document that describes the web service. You can write (customize) it using CFML. For instance:
http://subdomain.domain.com/api/wsdl.cfm?api=bsapi&customer=subdomain
Then just copy the WSDL generated by CF, and use it as a template for your custom WSDL page. Replace the parts of the WSDL that are subdomain-specific and return the XML document. Be mindful of whitespace (perhaps see CFSilent, CFSetting), and consider using CFHeader to set the mime type to "text/xml".
Do all the customers use the same WSDL? Then place the WSDL at a common URL for all customers.
I also think you need to find out exactly what the error message means. I don't see where it has anything to do with the URL being used. If it had mentioned the URL of another customer, I'd have understood.
Part of this may be due to my lack of understanding of how CF works. In particular, what is this "registering web services" that triggers the problem when two customers do it?
Did you realize that the URL in the <soap:address/> element in the WSDL is only a hint? In many clients, it can be overridden. In a .NET client, just set the Url property of the proxy class. This should allow you to have a single WSDL at a single location, and yet have your customers each reference the proper subdomain, assuming there's some way to convey that information to them. For instance, if there is a way for you to know which customer is making the call, then perhaps you could receive calls on one URL and then redirect to the proper URL, or else use a SOAP Routing infrastructure to route to the correct one.
I hope you are not changing the namespaces from one customer to another. Namespaces have nothing to do with URLs, even if they happen to look like URLs.
There is a namespace attribute for the cfcomponent tag. You should be able to use this, along with cgi.host_name (? I'm at home, without docs) to specify a namespace that matches the subdomain being queried.
Something like:
<cfcomponent namespace="http://#cgi.host_name#/api/v1n1/bsapi.cfc">
Have caught this error message when tried to CFINVOKE webservice from localhost by test script located on same localhost (but in different folder). Sounds 'buggish' for me.