views:

325

answers:

2

I'm having a couple of websites hosted different places, which I want to backup regularly.

However I only need the user-uploaded files, so I've made a simple Web service on each site, with the same definition:

public class BackupService : System.Web.Services.WebService
{
    [WebMethod]
    public string[] GetFileList()
    {
        // Get list from DB
    }
}

The namespace is obviously different, however I think it should be possible to use a single stub for this, and just call that stub with different URLs.

The problem is, I can't seem to find any examples of how to do this - so either it's not possible (which I doubt until proven wrong) or I just suck at searching.

Can anyone come up with an idea of how to do this ?

The reason I want to do it, is I regularly add new websites to my "backup list", and I don't want to recompile my backup software each time. Currently I don't backup the files, I just get the databases, and these I've just defined in an XML document, so each new website is just an entry in the XML.

My hope is that it's possible to do the same with the webservices, so I can just add the ASMX url in my XML file, and thus avoid recompiling.

+2  A: 

So what's the problem with deploying that web service to the various hosted (and different physical locations) and changing the web service endpoint URL in your SOAP client from your calling code?

Or am I missing the point of your question?

OK, having read your comment, here's a few more pointers.

All that Add Web Reference does, is, it generates a SOAP proxy client in your Reference.cs file. Because the contract for these is all the same, you only need to do this once.

Then, where you set use your SOAP client proxy in your calling code, set the Url to the appropriate .asmx endpoint (load it from your custom XML config or web.config):

YourWebServiceClient client = new YourWebServiceClient();
client.Url = "http://server/webservice/yourendpoint.asmx"; // get from config
string[] filenames = client.GetFileList();

That's all you should need to do. Hope it helps.

Also - ensure that for the different webservices, you don't change the webservice namespace. Keep it the same. It may be more convenient to use a URN namespace, rather than a URI, as it's tempting to change the namespace with the URI to stay in line with the URL of the webservice, however this is not necessary.

So for instance, mark your webservice up using a URN namespace:

[WebService(Namespace = "urn:your:mywebservice")]

And deploy that same webservice to the various locations.

Wim Hollebrandse
Well normally when I consume a web service in C# I add it as a web reference, which in turn generates a stub class for that particular service.If I were to do this for more than one location, I'll have to add a reference for each location, and thus add a new reference when a new location is created. This means I must add a reference, add some code to consume it and then recompile my backup software.Maybe I can just do something with the URL like you mention, but in that case I'm not sure how to do this.
Steffen
OK - edited my answer.
Wim Hollebrandse
I just tried this out, unfortunately I get an error when I change the Url and call it.Server did not recognize the value of HTTP Header SOAPAction: http://www.ckode.dk/GetFileList.I created the stub off of ckode.dk (which is an actual site, though danish) and then changed the Url prior to the call, but alas the ckode.dk part exists in the stub file in some attributes, like e.g. SoapDocumentMethodAttribute.Any ideas for working around this issue ?
Steffen
You need to make sure the endpoint you use is an actual ASMX endpoint Url. Compare the working one with the one you're trying to change it to.
Wim Hollebrandse
I've checked it, it's a working ASMX url - When typed into a browser it shows me the ASP.Net generated page for web services (where you can test webmethods and so forth)I do however use Visual Studio 2010 - could this have any impact ?
Steffen
The URN namespace detail was what fixed my problems - now it works like a charm - thanks alot :-)
Steffen
A: 

As an alternative, you could have a static class with the logic that the web service uses, and call that in each:

public class BackupService : System.Web.Services.WebService { [WebMethod] public string[] GetFileList() { return BackupHelper.GetFileList(); } }

public static class BackupHelper { public string[] GetFileList() { .. } }

Brian
I'm not quite certain what you mean by this, where would that static class reside, and how should it create a connection to the webservice ?
Steffen
@Brian: That's nothing to do with the question really. Steffen is asking about how to deploy web services to multiple sites, and having one SOAP client calling the various sites.
Wim Hollebrandse
@Wim I agree, and I did read the original post wrong (sorry about that), and also that's why I said as an alternative; you can have multiple services, but all the logic fits within one component, and each of the services calls the methods within the component.Sorry, this may have been no help at all. Hope this hasn't caused more confusion :-;
Brian