I am required to consume a SOAP web service with a Java program I am writing. I have a basic test .NET service on my server in a .asmx file. There are a bunch of complicated examples that I found on Google but can someone provide a short explination for me? It would be greatly appreciated. Thanks!
Here is my .asmx file.
<%# WebService Language="C#" Class="Example1" %>
using System.Web.Services;
[WebService(Namespace="urn:Example1")]
public class Example1 {
[ WebMethod ]
public string sayHello(string name) {
return "Hello " + name;
}
}
Maybe there is a different way I should be doing this? Thanks again.
You can use a tool that comes with the JDK called wsimport to parse your WSDL file and generate Java classes.
wsimport http://path/to/your?wsdl -d /desired/output/folder
You can then use the generated classes like so:
Example1Endpoint example1 = new Example1Service().getExample1Port();
System.out.println(example1.sayHello("tkcsam"));
Is your .Net service a "page" that you post a string to as a parm? I've had to talk to a few of those in the past (I wouldn't really call them "web services", but anyway....).
If that is the case, find out what you need to post. Use your Java to build the giant String that you need to feed to the page and then send it to the page as a parm and wait for the response String coming back. You'll have to parse that string then.
This is terribly inelegant, but it used to be how Microsoft did things. Not sure if it is true in your case. Otherwise if you do have a WSDL to work with then I'd probably use either Jack's answer or follow the comment by djhaskin987 as there are some frameworks listed there that will dynamically generate web service clients based on published web services (that have their WSDL published with them).
JAXWS is the standard technology for interacting with SOAP webservices in java. the default implementation in the oracle jdk is the metro stack, which has an extensive user guide.
Related
I have a problem here. Assume there's a basic calculator implemented in javascript hosted on a website ( I have googled it and to find an example and found this one: http://www.unitsconverter.net/calculator/ ). What I want to do is make a program that opens this website, enters some value and gets the return value. So, in our website calculator, the program:
- open the website
- enters an operand
- enters an operation
- enters an operand
- retrieve the result
Note: things should be done without the need to show anything to the user ( the browser for example ).
I did some search and found about HttpWebRequest and HttpWebRespond. But I think those can be used to post data to the server, which means, The file I'm sending data to must be php, aspx or jsp. But Javascript is client side. So, I think they are kind of useless to me in this case.
Any help?
Update:
I have managed to develop the web bot using WebBrowser Control tool ( found in System.Windows.Forms )
Here's a sample of the code:
webBrowser1.Navigate("LinkOfTheSiteYouWant"); // this will load the page specified in the string. You can add webBrowser1.ScriptErrorsSuppressed = true; to disable the script in a page
webBrowser1.Document.GetElementById("ElementId").SetAttribute("HTMLattrbute", "valueToBeSet");
Those are the main methods I have used to do what I wanted to.
I have found this video useful: http://www.youtube.com/watch?v=5P2KvFN_aLY
I guess you could use something like WatiN to pipe the user's input/output from your app to the website and return the results, but as another commenter pointed out, the value of this sort of thing when you could just write your own calculator fairly escapes me.
You'll need a JavaScript interpreter (engine) to parse all the JavaScript code on the page.
https://www.google.com/search?q=c%23+javascript+engine
What you're looking for is something more akin to a web service. The page you provided doesn't seem like it accepts any data in an HTTP POST and doesn't have any meaningful information in the source that you could scrape. If for example you wanted to programmatically make searches for eBay auctions, you could figure out how to correctly post data to it eg:
http://www.ebay.com/sch/i.html?_nkw=http+for+dummies&_sacat=267&_odkw=http+for+dummies&_osacat=0
and then look through the http response for the information you're looking for. You'd probably need to create a regular expression to match the markup you're looking for like if you wanted to know how many results, you'd search the http response for this bit of markup:
<div class="alt w"><div class="cnt">Your search returned <b>0 items.</b></div></div>
As far as clientside/javascript stuff, you just plain aren't going to be able to do anything like what you're going for.
It is a matter of API: "Does the remote website expose any API for the required functionality?".
Well web resources that expose interactive API are called web service. There are tons of examples (Google Maps for istance).
You can access the API -depending on the Terms & Conditions of the service- through a client. The nature of the client depends on the kind of web service you are accessing.
A SOAP based service is based on SOAP protocol.
A REST based service is based on REST principles.
So, if there is an accessible web service called "Calculator", then you can access the service and, for istance, invoke the sum method.
In your example, the calculator is a Javascript implementation, so it is not a web service and it cannot be accessed via HTTP requests. Though, its implementation is still accessible: it is the javascript file where the calculator is implemented. You can always include the file in your website and access its functions via javascript (always mind terms and conditions!!).
A very common example is the jQuery library stored in Google Libraries.
This is how I have currently managed to consume a particular Microsoft web service. Notice that it is located on an HTTPS server and that it requires a username, a password, and a .cer file to be installed in the operating system's "root certificate authorities".
WSHttpBinding binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.TransportWithMessageCredential;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.Security.Message.NegotiateServiceCredential = true;
binding.Security.Message.AlgorithmSuite
= System.ServiceModel.Security.SecurityAlgorithmSuite.Default;
binding.Security.Message.EstablishSecurityContext = true;
EndpointAddress endpoint = new EndpointAddress("https://address.of.service");
//"GreatClient" was created for me automatically by running
//"svcutil.exe https://address.of.service?wsdl"
GreatClient client = new GreatClient(binding, endpoint);
//Username and password for the authentication. Notice that I have also installed
//the required .cer certificate into the system's "root certificate authorities".
client.ClientCredentials.UserName.UserName = "username";
client.ClientCredentials.UserName.Password = "password";
//Now I can start using the client as I wish.
My question is this: How can I obtain all the information necessary so that I can consume the web service with a direct POST to https://address.of.service, and how do I actually perform the POST with C#? I only want to use POST, where I can supply raw XML data using POST directly to https://address.of.service and get back the result as raw XML data. The question is, what is that raw XML data and how exactly should I send it using POST?
(The purpose of this question: The reason I ask is that I wish to consume this service using something other than C# and .NET (such as Ruby, or Cocoa on Mac OS X). I have no way of knowing how on earth to do that, since I don't have any easy-to-use "svcutil.exe" on other platforms to generate the required code for me. This is why I figured that just being able to consume the service using regular POST would allow me to more easily to consume the service on other platforms.)
What you are attempting to do sounds painful to do now and painful to maintain going forwards if anything changes in the server. It's really re-inventing the wheel.
If you haven't considered it already, I would:
(a) Research whether you can use the metadata you have for the service and use a proxy generator native to your target plaform. There aren't many platforms that don't have at least some tooling that might get you part of the way if not all of it. Perhaps repost a question targetting Ruby folk asking what frameworks exist to consume an HTTPS service given it's WSDL?
(b) Failing that, if your scenario allows it I would consider using a proxy written in C# that acts as a facade for the service which translates it into something easier to consume (for example, you might use something like ASP.NET MVC WebAPI which is flexible and can easily serve up standards compliant responses over which you can maintain total control).
I suspect one of these may prove easier and more valuable than the road you are on at the moment.
I had to go through something similar when porting .NET WCF code to other platforms. The easiest approach I found was to enable message logging on the WCF client. This can be configured to save both envelope and body and once everything is working on the .NET side of the house, you can use the message log to have "known-good" XML request/response to port to other platforms.
I found this approach to be more elegant since I didn't have to add an additional behavior to log messages, and it can be easily enabled/disabled/tweaked in the config. The Service Trace Viewer Tool that ships with Visual Studio is also handy for reviewing the log files.
I think when you say that the service should be consumed from other platforms, which do not have proxy class generation logic, you can go with REST services. This will allow you to create input as simple string concatenation instead of complex XML. Though its applicability depends on the situation.
Check this discussion : http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/6907d765-7d4c-48e8-9e29-3ac5b4b9c405/
As far as the certificate is concerned, refer http://msdn.microsoft.com/en-us/library/ms733791.aspx on how to configure it.
I know this is not a very precise answer, but you will be the best person to evaluate above procedure, hence posted. Hope it helps.
What I'll do:
1- Create a small c# app that can post on this webservice (using svcutil). And modify it to show the XML send/received. To view the xml there are several ways: logging, wireshark etc. To add it directly to the small app there is another question here that give a good answer.
2- Once you know what you have to send, you can do it in c# like this:
// implement GetXmlString() to return the XML to post
string xml = GetXmlString();
// create the url
string url = new UriBuilder("http","address.of.service",80).ToString();
// create a client object
using(System.Net.WebClient client = new System.Net.WebClient()) {
// performs an HTTP POST
client.UploadString(url, xml);
}
I'm not a .NET programmer but I've had to interoperate with a few .NET services and have lots of SOAP/WSDL experience. Sounds like you've captured the XML for your service. The other problem you'll face is authentication. OOTB, .NET web services use NTLM for authentication. Open-source language support for NTLMv2 can be hit and miss (although a quick google search pulled up a few possibilities for ruby), and using NTLM auth over HTTP may be something that you have to wire together yourself. To answer a question above: where are the auth creds? If the service is using NTLM over the wire, authentication is happening at some layer below HTTP. If the service is using NTLM to authenticate HTTP, your NTLM creds are in the HTTP Authorization header. You should be able to tell with wireshark where they are. You'll also probably need a SOAPAction header; this can also be sniffed with wireshark. For the C# client, I'm sure there are docs explaining how to add headers to your request.
I am trying to connect to Magento API using C#. I am using Magento Go service and from what I've read I am able to use their API - I hope I am not wrong here. So here is what I did:
I added a Service Reference to http://mydomain.gostorego.com/api/v2_soap?wsdl=1, and just adding a service worked fine. Now I created a test class with GetStuff() method, which looks like this:
using ww.Feeds.MagnetoGoService;
public static string GetStuff()
{
MagnetoGoService.Mage_Api_Model_Server_V2_HandlerPortTypeClient s = new MagnetoGoService.Mage_Api_Model_Server_V2_HandlerPortTypeClient();
var login = s.login("username here", "key here");
return login.ToString();
}
When I run the program I get an error in first line saying:
Could not find default endpoint element that references contract 'MagnetoGoService.Mage_Api_Model_Server_V2_HandlerPortType' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.
Any ideas what this may be? Do I have to set something up in my Magento Go settings? Or maybe using Magento Go is not allowing API access?
Thanks a lot.
Forget SOAP with c# you will pull your hair out. Download Charls Cook's xml-rpc api libary for c# and use the xml-rpc method. You won't get all the snazzy intellisense but at least it will work. There's also c# solution from ez.newsletter they released with Cook's library demonstrating how to use 80% of the magento api calls.
Cook's library xml-rpc.net
http://www.xml-rpc.net/
ez.newsletter solution
http://code.google.com/p/csharlibformagexmlrpcapi/
If anyone ever has problems with this, my solution was this:
I used the reference in one project, but I actually called the class and had main program in another project. You need your Service reference to be in each project wherever you're using it. That fixed it! Alternatively you can create a new BasicHttpBinding() and putt all the options from app.config/web.config into that binder, then you don't need to reference to Service everywhere. I hope that helps!
I don't have much experience with web services, but I think I have a problem for which a web service would work great.
My company has just purchased a .net version of Cete Pdf Merger (great product btw). We use both .Net & asp code and will likely use java in the future as well.
The scenario is that one technology (asp, java, .net) would have a list of raw data such as an array of field names & values. This data would be posted to the web service that would then open a given pdf, match pdf form fields to the field names array, grab the corresponding value, populate it on the pdf, and then stream the pdf back to the user to download.
Does this seem feasible? Any gotcha's I might run into that you know of? Any preferred method of doing (Web Services, WCF, ???)
Short answer: WCF
Longer answer is: you seem to be making a distinction between WCF and "web services". Perhaps you're thinking of the old ".asmx" web services. Microsoft now considers them to be "legacy software", and suggests you use WCF for all new web service development.
If you're going to use web services with .NET, I recommend using WCF (Windows Communication Foundation).
WCF (MSDN) is a good choice, but you if you would like to provide a user interface (such as an HTML form to type in the field values), you could use a regular web form and post to a page with HTTP, returning the PDF output by streaming the response with the appropriate MIME-type.
This sounds like a great idea. You could use an .asmx web service (others might look down on .asmx).
Suggest creating a webmethod like so:
(this example is rough around the edges, but it's just to describe the general idea)
[WebMethod]
public void CreatePdfIncomeTax(IncomeTaxForm itf)
{
// integrate with Cete Pdf Merger
string fileName = SomePdfMerging(itf);
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "inline; filename=foo.pdf");
Response.WriteFile(path);
Response.Flush();
Response.End();
}
...
// a class that the caller would populate as param to the webmethod
public class IncomeTaxForm
{
public string FirstName {get;set;}
public string AddressLine1 {get;set;}
...
}
I've done pretty much that exact thing but using Aspose as the PDF component. We used an .asmx web service and not WFC which is what I wanted. I would certainly agree with everyone else that say that WCF is the way to go. I know that I would have preferred that, but the decision was unfortunately not mine to make.
Where can I find the RAW/object data of a SOAP request in C# when using WebServices.
Can't find it anywhere. Shouldent it be available in the HttpContext.Current.Request object ?
Shouldent it be available in the HttpContext.Current.Request object ?
No, it shouldn't.
What are you trying to accomplish? If you just want to see that data so you can log it, or as an aid to debugging, then see the example in the SoapExtension class. It's a working sample of an extension that can log input and output as XML. I've used a modified version of it myself.
If you're just looking to debug your web service, then you can install Fiddler, and that allows you to inspect the data sent to and from your web service.
It sounds like you're going to have to go lower level on your implementation if you want to see the raw XML. Check out the generic handler (ASHX extension). This will allow you to deal with the request/response streams directly. It's very low level, but gives you full control over the service lifecycle.
I found
Request.Params[null]
refers to the RAW data posted to the page in C# ASP.NET.