Trouble connecting to WSDL
I have been given an SDK that uses a WSDL file to connect to a web service. I was given sample code in the README along with step by step instructions on how to setup the file, but even with following everything the code will not compile.
The instructions and 开发者_JAVA百科code are here. http://dl.dropbox.com/u/3425987/README.txt
The WSDL file is here http://dl.dropbox.com/u/3425987/arm-inlined.wsdl
It does not seem to find ArmServiceImplService.
Any help with what I am doing wrong is greatly appreciated.
Edit: The only thing I am doing that doesn't follow the instructions is I am using VS 2010, not 2008. I don't imagine that this would be the issue, but I am running out of other options.
As part of a WSDL there is a location/URL for accessing the SOAP Service - according to the WSDL it is:
http://localhost:8080/ARM/ARM/
This location would lead to your client trying to access port 8080 on the system it is running on... unless you have a SOAP service running there this won't work (connection refused and/or timeout)...
From the sample source in your README:
// TODO: Replace with live server URL when ready
armService.Url = "http://localhost:8081/ARM/ARM/";
This comment tells you to replace the URL with the live server URL...
From your question I assume that you haven't replaced the URL/don't have the live server URL ?
EDIT - according to comment by OP:
IF your code is not compiling you seem the have skipped Point 7 and following from the instructions in the README
7) After Visual Studio opens the newly created project, right-click on SampleArmClient in the Solution Explorer and select "Add Service Reference"
8) In the "Add Service Reference" dialog box, in the box labeled URL enter either: a) The URL to the WSDL from the real or "mock" ARM Service (For instructions on starting the "mock" ARM Service, please see section 7.) For example, if the "mock" service was started on port 8081, the URL to the service would be http://localhost:8081/ARM/ARM?WSDL.Please note that the URL to be used from within your code is http://:/ARM/ARM. It does not contain the "?WSDL" - that suffix is strictly for discovering the web service. b) The location on disk that the wsdl is located at in the unpacked distribution. For example, if the distribution was unpacked into the c:/temp directory, the URL would be c:\temp\arm\src\main\resources\gov\hud\arm\wsdl\arm-inlined.wsdl. (This is the version of WSDL with the schema included in it so that .NET can resolve the references without an external schema.)
One last piece of the puzzle for you. I went back through my email to see what exactly the issue was with 7/8 in the instructions and this is what I reported to HUD:
In the instructions you provide for Visual Studio 2008, item number 8 tells you to add a service reference. Now part of this I got right and part I didn't because I'm too new to .net, but, you need to adjust that line to read add a new Web Reference (service reference isn't an option anymore) instead of service reference, and it's very important to tell them to name it ARM
This also applies to VS2010 which is what I managed to get working in last night. And just so you know, I edited the original code post to remove the lines that were breaking so just make the changes to the id's and paths and you should be good to go. I ran it against the dev url I got from hud support (Andrey) rather than trying to run the service on my machine. I suggest you do the same because if their samples are this far out of date, then the service they provide as a sample is too I would bet. The dev url worked pretty well, though I did find a few discrepencies there too. They've been fixed since though so it should be the best place to test your xml submission files.
Well, will wonders never cease. I just gave another shot at the code below. Of course, it gave me an error here:
api client = new api();
client.PreAuthenticate = true;
client.Credentials = new NetworkCredential(credentials.UserName, credentials.Password);
So I rem'd it out and reran and I got a received reply back from HUD. How about that!! It only sends the agency file, but it connected, sent the file, and got the response back to me. Now all I have to do is create the other functions I need and a way to pass the credentials for each company to it and how to get the responses back so I can log them in my asp site, and all will be well with the world again. The bin file shows it's creating an exe so hopefully I can call that from my asp code sending it the credentials and path to the files for each company, and it can send them one at a time, get the response and log it. Then run the responses through later to insure all data passed validation.
Still quite a bit of work to do, but, this is a great stride forward. Hope this helps and let me know if you beat me to the punch. I'm a contractor and may not ever get paid to complete this side of the project, but it's nice to know I can now go this route. I may just do it to satisfy my need to beat the machine. :) But if you beat me to the punch please send me the final and I will insure that HUD gets a full update so noone else has to beat their heads against the wall.
First of all, I am having the same issue so I don't have all the answers yet. But using VS2010 you do need to add some code to make the connection. The issue is you have to authenticate in the header and with VS2008 and above, it doesn't do that.
Now, there are other issues as well. If you want to run databag 4 that is. The code they give us is for an earlier databag and doesn't run the databag 4 send/receive functions because it doesn't include samples of them. I've requested they include it, but who knows how long that will take.
Also, as noted above, step 7 /8 is crucial and the directions are incorrect. I've notified support about that too, but as of my last check, they haven't updated the notes to include that. Sorry I don't remember the specifics right now, but it was something failrly simple I caught by just reading the screens while I was doing it the third or fourth time.
As you will note with the code below, I have made some progress in the right direction, but I'm not a .net developer. I'm a classic asp guy, so I am still unable to get it fully functional this way and use the SOAP UI tool for our uploads at present. Which means I have to do all 30 companies by hand, one file at a time. 4 files each. Still, I'm done in a day and paid well for my time so it's ok, but I'm frustrated with the support I've gotten so far so if you figure out more from this, please let me know.
using System;
using System.Collections.Generic;
using System.Text;
using ARMService.ARM;
using System.Net;
using System.IO;
using System.Threading;
namespace ARMService
{
public partial class api : System.Web.Services.Protocols.SoapHttpClientProtocol
{
//added "protected overide" to get past the pre-auth issue with VS2008 and above since I'm running VS2010
//Now this is in place, you will send the authentication header at the first request.
//Since this implementation is using the credentials from the WebClientProtocol, you will be required to set these in advance.
//But I guess you were doing that anyways. Furthermore, I chose to only do the pre-authentication if the PreAuthenticate
//property was set to true. (deactivated if statement so it will always preauth.)
//So if you want to consume this service, this is how you would initiate it;
//api client = new api();
//client.PreAuthenticate = true;
//client.Credentials = new NetworkCredential("username", "password");
protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(uri);
// if (PreAuthenticate) //removed if statement because I want all items to pre-auth
// {
NetworkCredential networkCredentials = Credentials.GetCredential(uri, "Basic");
if (networkCredentials != null)
{
byte[] credentialBuffer = new UTF8Encoding().GetBytes(networkCredentials.UserName + ":" + networkCredentials.Password);
request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(credentialBuffer);
}
else
{
throw new ApplicationException("No network credentials");
}
// }
return request;
}
}
class Program
{
static void Main(string[] args)
{
ArmServiceImplService armService = new ArmServiceImplService();
// TODO: Replace with live server URL when ready
armService.Url = "https://HUD will give you the url/ARM/ARM/";
armService.PreAuthenticate = true;
NetworkCredential credentials = new NetworkCredential();
// TODO: Replace with userid/password issued by HUD for HCS system when ready
credentials.UserName = "yourHUDMXnumber";
credentials.Password = "yourpassword";
armService.Credentials = credentials;
//These three removed per second post and fixed the last issue
//api client = new api();
//client.PreAuthenticate = true;
//client.Credentials = new NetworkCredential(credentials.UserName, credentials.Password);
//removed for now to try only postAgencyData
//doPing(armService);
//doGetReference(armService);
//postSubmissionResponse submissionId = doPostSubmission(armService);
//fixed
postSubmissionResponse psr = AgencyData(armService);
while (dopostAgencyDataResponse(armService, psr) != true)
{
// sleep for 60 seconds before checking agin.
Thread.Sleep(60000);
}
}
private static void doGetReference(ArmServiceImplService armService)
{
getReference getReference = new getReference();
// TODO: Replace 80000 with your agency HCS id.
getReference.agcHcsId = 80000;
getReference.referenceId = 0;
referenceItem[] referenceItems = armService.getReference(getReference);
foreach (referenceItem referenceItem in referenceItems)
{
Console.WriteLine(referenceItem.id);
Console.WriteLine(referenceItem.name);
Console.WriteLine(referenceItem.longDesc);
Console.WriteLine(referenceItem.shortDesc);
}
}
private static void doPing(ArmServiceImplService armService)
{
ping pingIn = new ping();
// TODO: Replace 80000 with your agency HCS id.
pingIn.agcHcsId = 80000;
string pingString = armService.ping(pingIn);
Console.WriteLine(pingString);
}
private static postSubmissionResponse AgencyData(ArmServiceImplService armService)
{
postAgencyData AgencyData = new postAgencyData();
submissionHeader40 header = new submissionHeader40();
// TODO: Replace 80000 with your agency HCS id.
header.agcHcsId = 80000;
header.agcName = "Your Agency Name";
// TODO: Replace 8 with your CMS vendor id issued to you by ARM Development Team.
header.fiscalYearId = 17;
header.reportingPeriodId = 3;
header.cmsVendorId = yourVendorNUmber;
AgencyData.submissionHeader40 = header;
// TODO: Replace fake databag with valid databag of your own
FileStream file = new FileStream("c:/Users/Public/Documents/AgencyProfileData.xml", FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader(file);
string str = sr.ReadToEnd();
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
AgencyData.submissionData = encoding.GetBytes(str);
//fixed
postSubmissionResponse psr = armService.postAgencyData(AgencyData);
Console.WriteLine("Submitted Data returned id : " + psr.submissionId);
return psr;
}
private static Boolean dopostAgencyDataResponse(ArmServiceImplService armService,
postSubmissionResponse postAgencyDataResponse)
{
getSubmissionInfo getSubmissionInfo = new getSubmissionInfo();
// TODO: Replace 80000 with your agency HCS id.
getSubmissionInfo.agcHcsId = 80000;
getSubmissionInfo.submissionId = postAgencyDataResponse.submissionId;
getSubmissionInfoResponse response = armService.getSubmissionInfo(getSubmissionInfo);
Console.WriteLine("SubmissionInfo Status Date = " + response.statusDate);
Console.WriteLine("SubmissionInfo Status Message = " + response.statusMessage);
// if Done or Error returned, then return true to stop polling server.
if (response.statusMessage.Equals("DONE") || response.statusMessage.Contains("ERROR"))
{
return true;
}
else
{
return false;
}
}
}
}
I just thought I would follow up with this. The above solution worked for all but the larger of the files I needed to transmit. To correct that, I simply removed (cut) the protected override statement from the program.cs page and copied it into the references.cs page and made just two adjustments. The new statement is:
protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(uri);
if (PreAuthenticate)
{
NetworkCredential networkCredentials = Credentials.GetCredential(uri, "Basic");
if (networkCredentials != null)
{
byte[] credentialBuffer = new UTF8Encoding().GetBytes(networkCredentials.UserName + ":" + networkCredentials.Password);
request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(credentialBuffer);
}
else
{
throw new ApplicationException("No network credentials");
}
}
request.KeepAlive = false;
return request;
}
Once this was saved, I was able to stay connected long enough to transfer really large files.
精彩评论