Using the Product Mapping File Upload Web Service
Yesterday we released updates to our web services offerings. These updates include the ability to automate the upload of the product mapping XML, getting a list of products mapped, getting the list of mapped files for a product, deleting a mapped file from a product, deleting mapped products and deleting a mapped file from multiple products.
This blog post lists the code (in C#) required to access our web services for uploading a product mapping file.
The code does 2 things:
- Login to the Winqual portal, since the authentication web service uses SOAP the code for accessing the authentication web service without a proxy is a bit cumbersome.
- Use the .NET WebClient class (you can also use the HttpWebRequest and HttpWebResponse classes for this) to upload the product mapping file and get the response.
Code for using the product mapping file upload service (also attached as a CS file):
1: string filePath = "path to the product mapping XML file e.g. c:\upload\CoolApplication.xml";
2: string baseUrl = "https://winqual.microsoft.com";
3: string userName = "your winqual username";
4: string password = "your winqual password";
5: //
6: // login
7: //
8: string loginUrl = string.Format(
9: "{0}/services/Authentication/Authentication.svc/BasicTicket" 10: , baseUrl);
11: string request = string.Format(
12: "<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope
xmlns:soap=\http://schemas.xmlsoap.org/soap/envelope/\
xmlns:xsi=\http://www.w3.org/2001/XMLSchema-instance\
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><soap:Body>
<GetBasicTicket
xmlns=\"https://winqual.microsoft.com/Services/Authentication/\">
<userName>{0}</userName><password>{1}</password></GetBasicTicket></soap:Body></soap:Envelope>"
13: , userName
14: , password);
15: WebClient loginClient = new WebClient();
16: loginClient.Headers.Add(HttpRequestHeader.ContentType, "text/xml");
17: loginClient.Headers.Add(
18: "SOAPAction",
19: "https://winqual.microsoft.com/Services
/Authentication/IBasicTicket/GetBasicTicket");
20: string loginResponse = loginClient.UploadString(loginUrl, request);
21:
22: //
23: // parse the response to get the encrypted ticket out
24: // TODO: Handle condition where the ticket is null in case of bad pwd,
bad username or some other error
25: //
26:
27: int startingIndex = loginResponse.IndexOf("<GetBasicTicketResult>") + "<GetBasicTicketResult>".Length;
28: int endingIndex = loginResponse.IndexOf("</GetBasicTicketResult>"); 29: string encryptedTicket = loginResponse.Substring(startingIndex
, (endingIndex - startingIndex));
30:
31: //
32: // upload file
33: //
34: WebClient webClient = new WebClient();
35: webClient.Headers.Add("encryptedTicket", encryptedTicket); 36: byte[] responseBytes = webClient.UploadFile(baseUrl
+ "/services/wer/user/fileupload.aspx", filePath);
37:
38: //
39: // the response that the WebClient gets may contain an updated ticket, so get that
40: //
41: if (webClient.ResponseHeaders["encryptedTicket"] != null)
42: { 43: encryptedTicket = webClient.ResponseHeaders["encryptedTicket"];
44: }
45:
46: //
47: // get the response
48: //
49: UTF8Encoding encoding = new UTF8Encoding();
50: string fileUploadResponse = encoding.GetString(responseBytes);
51:
52: //
53: // TODO: Check the response XML for success or error message
54: //
55:
56: return fileUploadResponse;
The XML response from the authentication service will be similar to the following when the login is successful:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<GetBasicTicketResponse xmlns="https://winqual.microsoft.com/Services/Authentication/">
<GetBasicTicketResult>encrypted ticket string</GetBasicTicketResult>
</GetBasicTicketResponse>
</s:Body>
</s:Envelope>
The XML response from the authentication service in case of a login failure will be similar to the following:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<GetBasicTicketResponse xmlns="https://winqual.microsoft.com/Services/Authentication/">
<GetBasicTicketResult a:nil="true" xmlns:a="http://www.w3.org/2001/XMLSchema-instance" />
</GetBasicTicketResponse>
</s:Body>
</s:Envelope>
The XML response when the upload is successful is similar to the following ATOM output:
<?xml version="1.0" encoding="utf-8" ?>
<feed xmlns=http://www.w3.org/2005/Atom
xmlns:wer=http://schemas.microsoft.com/windowserrorreporting
wer:status="ok">
<title>Feed Success</title>
<link rel="alternate" type="text/html" href="https://winqual.microsoft.com/services/wer/user/fileupload.aspx" />
<updated>2009-06-12 19:28:28Z</updated>
<id>Success</id>
<entry>
<updated>2009-06-12 19:28:28Z</updated>
<published>2009-06-12 19:28:28Z</published>
<title>File uploaded successfully</title>
<id>File uploaded successfully</id>
<wer:additionalInformation />
</entry>
</feed>
You can check the file upload by going to the website:
https://winqual.microsoft.com/member/wer/user/ManageProductMappings.aspx
Once you sort the table by the Map Date column in descending order, you should see your uploaded product.

You can see the files for the product uploaded by clicking the icon under the File Mappings column.