Consume Rest API X-pagination from header - c#

How can I extract the X-Pagination header from a response and use the next link to chain requests?
I've tried in both Postman and C# console application with RestSharp. No success.
Easiest would be a small console application to test. I just need to iterate through the pages.
This is what I get back in the headers X-Pagination:
{
"Page":1,
"PageSize":20,
"TotalRecords":1700,
"TotalPages":85,
"PreviousPageLink":"",
"NextPageLink":"www......./api/products/configurations?Filters=productid=318&IncludeApplicationPerformance=true&page=1",
"GotoPageLinkTemplate":"www..../api/products/configurations?Filters=productid=318&IncludeApplicationPerformance=true&page=0"
}

In Postman you simply retrieve the header, parse it into a Json object then use the value to set a link for your next request.
Make your initial request then in the Test tab do something like:
var nextPageLinkJson = JSON.parse(pm.response.headers.get("X-Pagination"));
var nextPageLink = nextPageLinkJson.NextPageLink;
pm.environment.set("nextPageLink", nextPageLink);
If you don't know how many pages you're going to have then you'll have to play with conditions when to set the nextPageLink variable and what not but that's the general idea.
You can set the request to run using the new link with postman.setNextRequest("request_name") as well.
Additionally this approach will only work in collection runner.

Related

Getting started with soap web service client c#

My boss asked how long it would take to build a client to access a web service that will send and receive some basic data and embedded documents. Just starting playing with it to see what's involved. I have been doing web and desktop development for about 20 years but have literally never touched a web service so with that I'm at the extreme newb level.
So far I used the wsdl to create the ServiceReference1 and I can see the methods in intellisense but I don't have the first clue where to start with calling the methods, passing parameters and consuming the response. I feel stupid because I'm sure it's pretty simple but just flailing at the code and looking for on point examples has gotten me nowhere. Usually I can find something through google in minutes that is exactly on point but not having luck here. Would appreciate a push in the right direction.
So basic questions. Proper way to make the calls. How and where to land the returned data. How to add parameters.
Here is my first attempt. This gets a simple list and has no parameters. The result in fiddler returns data but there is a runtime type mismatch error which I think is caused by some stray characters leading the response which appear to be caused by chucking, what ever that is. The response starts with 1ffs every time then contains the remainder of the xml. Secondarily I need to get the list into a dataset or some other container but I was hoping to just be able to step into the code and see a result
ServiceReference1.FilingInfoClient webservice = new FilingInfoClient();
ServiceReference1.courtListRequest cr = new ServiceReference1.courtListRequest();
ServiceReference1.courtListResponse lr = new ServiceReference1.courtListResponse();
lr = webservice .getCourtList(cr);
This is essentially the same but takes a date param. When I run this fiddler shows the parameter is not being sent. No other errors but I'm sure only because it exploded immediately.
ServiceReference1.FilingInfoClient webservice = new FilingInfoClient();
ServiceReference1.messageListRequest mr = new ServiceReference1.messageListRequest();
ServiceReference1.MessageListResponse mlr = new ServiceReference1.MessageListResponse();
mr.latestMessagePullTimestamp = DateTime.Now.AddDays(-5);
mr.endTimestamp = DateTime.Now;
mlr.latestMessagePullTimestamp = DateTime.Now;
mlr = webservice.getMessageList(mr);
This is the info provided by the web service host
<x:Envelope xmlns:x="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:urn1="urn:green:partner:ws:schema:FilingInfo">
<x:Header/>
<x:Body>
<urn1:getcourtList>
<urn1:courtListRequest/>
</urn1:getcourtList>
</x:Body>
</x:Envelope>
<x:Envelope xmlns:x="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:urn1="urn:green:partner:ws:schema:FilingInfo">
<x:Header/>
<x:Body>
<urn1:getMessageList>
<urn1:messageListRequest>
<urn1:latestMessagePullTimestamp>?</urn1:latestMessagePullTimestamp>
</urn1:messageListRequest>
</urn1:getMessageList>
</x:Body>
</x:Envelope>
we've got request and response pairs for each operation in the webservice. think like request => input, response => output, operation => method.
the webservice is an API. things that consume APIs are clients. the WSDL describes the API's operations and their requests and responses. tools like visual studio know how to read WSDLs and build C# code to perform those (SOAP) operations under-the-hood. this is the client (here FilingInfoClient). visual studio'll also generate classes representing each request and response.
this allows for a familiar programming experience. you call a method, give it some input, and it returns some output.
using (var client = new FilingInfoClient())
{
var request = new courtListRequest
{
//TODO fill in relevant properties
};
var response = client.getCourtList(request);
}

CustomVision API returns "Operation returned an invalid status code: 'NotFound'"

I am using the Nuget package Microsoft.Azure.CognitiveServices.Vision.CustomVision.Prediction
I have created a Custom Vision application in the Custom Vision portal and obtained API keys and a project ID.
Whenever I try to make a request to the API, I always get the following exception thrown:
HttpOperationException: Operation returned an invalid status code
'NotFound'
Here is my code:
HttpClient httpClient = new HttpClient();
CustomVisionPredictionClient customVisionPredictionClient = new CustomVisionPredictionClient(httpClient, false)
{
ApiKey = PredictionKey,
Endpoint = PredictionEndpoint,
};
var result = customVisionPredictionClient.PredictImageAsync(CUSTOM_VISION_PROJECT_GUID, imageData);
I have tried several different endpoints:
https://southcentralus.api.cognitive.microsoft.com/customvision/v2.0/Prediction
https://southcentralus.api.cognitive.microsoft.com/customvision/Prediction/v1.0
https://southcentralus.api.cognitive.microsoft.com/customvision/v1.1/Prediction
though on the portal the listed one is the first of the list. I have also succesfuly exported my app on Azure, which gives me the second endpoint in the list but with no more success.
I have also set a default iteration as suggested in a similar issue that I found ( CustomVision: Operation returned an invalid status code: 'NotFound' ).
I have tried this sample https://github.com/Microsoft/Cognitive-CustomVision-Windows/tree/master/Samples/CustomVision.Sample which uses a deprecated windows client, to at least ensure my project information are correct and I was able to access the API.
Any insight would be appreciated
For the .NET client SDK, you need to specify the base endpoint URL without the version or the rest of the path. The version is automatically added by the client SDK. In other words, you'll want (assuming SouthCentralUS is your region):
PreditionEndpoint = "https://southcentralus.api.cognitive.microsoft.com";
CustomVisionPredictionClient customVisionPredictionClient = new CustomVisionPredictionClient()
{
ApiKey = PredictionKey,
Endpoint = PredictionEndpoint,
};
var result = customVisionPredictionClient.PredictImageAsync(CUSTOM_VISION_PROJECT_GUID, imageData);
As an aside, note that unless you want to fine-tune the behavior, you don't need to pass in an HttpClient object to CustomVisionPredictionClient constructor.
If you need more sample code, please take a look at the QuickStart.
How to use the Prediction API
If you have an image URL:
your endpoint would be something like this
https://southcentralus.api.cognitive.microsoft.com/customvision/v2.0/Prediction/{Project-GUID}/url?iterationId={Iteration-ID}
Set Prediction-Key Header to : predictionId
Set Content-Type Header to : application/json
Set Body to : {"Url": "https://example.com/image.png"}
Or If you have an image file:
Endpoint would be like
https://southcentralus.api.cognitive.microsoft.com/customvision/v2.0/Prediction/{ProjectGuid}/image?iterationId={Iteration-Id}
Set Prediction-Key Header to : Predcition-key
Set Content-Type Header to : application/octet-stream
Set Body to : <image file>
Remember, you can mark an iteration as Default so you can send data to it without specifying an iteration id. You can then change which iteration your app is pointing to without having to update your app.
Check my other answer on the similar issue using python
Python custom vision predictor fails
Hope it helps.

How to get data from a client on load?

I'm aware that data can be passed in through the URL, like "example.com/thing?id=1234", or it can be passed in through a form and a "submit" button, but neither of these methods will work for me.
I need to get a fairly large xml string/file. I need to parse it and get the data from it before I can even display my page.
How can I get this on page load? Does the client have to send a http request? Or submit the xml as a string to a hidden form?
Edit with background info:
I am creating a widget that will appear in my customer's application, embedded using C# WebBrowser control, but will be hosted on my server. The web app needs to pass some data (including a token for client validation) to my widget via xml, and this needs to be loaded in first thing when my widget starts up.
ASP.NET MVC 4 works great with jQuery and aJax posts. I have accomplished this goal many times by taking advantage of this.
jQuery:
$(document).ready(function() {
$.ajax({
type: "POST",
url: "/{controller}/{action}/",
data: { clientToken: '{token}', foo: 'bar',
success: function (data, text) {
//APPEND YOUR PAGE WITH YOUR PARSED XML DATA
//NOTE: 'data' WILL CONTAIN YOUR RETURNED RESULT
}
});
});
MVC Controller:
[HttpPost]
public JsonResult jqGetXML(string clientToken, string foo)
{
JsonResult jqResult = new JsonResult();
//GET YOUR XML DATA AND DO YOUR WORK
jqResult.Data = //WHATEVER YOU WANT TO RETURN;
return jqResult;
}
Note: This example returns Json data (easier to work with IMO), not XML. It also assumes that the XML data is not coming from the client but is stored server-side.
EDIT: Here is a link to jQuery's Ajax documentation,
http://api.jquery.com/jQuery.ajax/
Assuming you're using ASP.NET, since you say it's generated by another page, just stick the XML in the Session state.
Another approach, not sure if it helps in your situation.
If you share the second level domain name on your two sites (i.e. .....sitename.com ) then another potential way to share data is you could have them assert a cookie at this 2nd level with the token and xml data in it. You'll then be provided with this cookie.
I've only done this to share authentication details, you need to share machine keys at a minimum to support this (assuming .Net here...).
You won't be able to automatically upload a file from the client to the server - at least not via a browser using html/js/httprequests. The browser simply will not allow this.
Imagine the security implications if browsers allowed you to silently upload a file from the clients local machine without their knowledge.
Sample solution:
Background process imports xml file and parses it. The background process knows it is for customer YYY and updates their information so it know the xml file has been processed.
A visitor goes to the customer's web application where the widget is embedded. In the markup of the widget the customer token has been added. This could be in JavaScript, Flash, iFrame, etc.
When the widget loads, it makes a request to you app which then checks to see if the file was parsed for the provided customer (YYY) if it has, then show the page/widget.
If the XML is being served via HTTP you can use Liqn to parse the data.
Ex.
public partial class Sample : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string url = "http://news.yahoo.com/rss/";
var el = XElement.Load(url).Elements("channel");
StringBuilder output = new StringBuilder();
foreach (var c in el.Elements())
{
switch (c.Name.LocalName.ToLower())
{
case "title":
output.Append(c.Value);
output.Append("<br />");
break;
}
}
this.Label1.Text = output.ToString();
}
}
It is not exactly clear what the application is and what kind of options you have, and what kind of control over web server you have.
If you are the owner of the web server/application your options are way wider. You can first send a file to web-server with HTTP POST or PUT, including a random token, and then use the same token for GET with token in the query string
or use other options, applicable to third party-owned websites
if you are trying to consume some auth api, learn more about it. since you are hosting web browser control, you have plenty of options to script it. including loading whatever form, setting textarea or hidden field text with your xml and then simulating a submit button click. you can then respond to any redirects and html responses.
you can also inject javascript inside the page that would send it to server with ajax request.
the choice heavily depends on the interaction model.
if you need better advice, it would be most helpful if you provided sample/simplified url/url pattern, form content, and sequence of events that is expected from you from code/api/sdk perspective. they are usually quite friendly.
There are limited number of ways to pass data between pages. Personally for this I would keep in session during the generating page and clear it when it is retrieved in the required page.
If it is generated server side then there is no reason to retrieve it from client side.
http://msdn.microsoft.com/en-us/library/6c3yckfw(v=vs.100).aspx
Create a webservice that your C# app can POST the XML to and get back HTML in response. Load this HTML string into the WebBrowser control rather than pointing the control to a URL.

Check if website is online with ASP.NET C#?

I would like to know how to check if a website is offline or online using C#?
Try to hit the URL using HttpWebClient over an HTTP-GET Request. Call GetResponse() method for the HttpWebClient which you just created. Check for the HTTP-Status codes in the Response.
Here you will find the list of all HTTP status codes. If your request status code is statrting from 5 [5xx] which means the site is offline. There are other codes that can also tell you if the site is offline or unavailable.You can compare the codes against your preferred ones from the entire List.
//Code Example
HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create("http://www.stackoverflow.com");
httpReq.AllowAutoRedirect = false;
HttpWebResponse httpRes = (HttpWebResponse)httpReq.GetResponse();
if (httpRes.StatusCode==HttpStatusCode.NotFound)
{
// Code for NotFound resources goes here.
}
// Close the response.
httpRes.Close();
First off, define "online" and "offline". However, if your codebehind code is running, your site is online.
For my web apps, I use a setting called Offline, which admin can set on/off.
Then I can check that setting programmatically.
I use this Offline setting, to show friendly maintenance message to my users.
Additionally you can use App_Offline.htm,
reference :
http://www.15seconds.com/issue/061207.htm
http://weblogs.asp.net/scottgu/archive/2005/10/06/426755.aspx
If you mean online/offline state that controls IIS, then you can control this, with custom Web Events (Application Lifetime Events)
http://support.microsoft.com/kb/893664
http://msdn.microsoft.com/en-us/library/aa479026.aspx
You can use Pingdom.com and its API's. Check the source code of the 'Alerter for Pingdom API' at the bottom of this page

How do I get a value from an XML web service in C#?

In C#, if I need to open an HTTP connection, download XML and get one value from the result, how would I do that?
For consistency, imagine the webservice is at www.webservice.com and that if you pass it the POST argument fXML=1 it gives you back
<xml><somekey>somevalue</somekey></xml>
I'd like it to spit out "somevalue".
I think it will be useful to read this first:
Creating and Consuming a Web Service (in .NET)
This is a series of tutorials of how web services are used in .NET, including how XML input is used (deserialization).
I use this code and it works great:
System.Xml.XmlDocument xd = new System.Xml.XmlDocument;
xd.Load("http://www.webservice.com/webservice?fXML=1");
string xPath = "/xml/somekey";
// this node's inner text contains "somevalue"
return xd.SelectSingleNode(xPath).InnerText;
EDIT: I just realized you're talking about a webservice and not just plain XML. In your Visual Studio Solution, try right clicking on References in Solution Explorer and choose "Add a Web Reference". A dialog will appear asking for a URL, you can just paste it in: "http://www.webservice.com/webservice.asmx". VS will autogenerate all the helpers you need. Then you can just call:
com.webservice.www.WebService ws = new com.webservice.www.WebService();
// this assumes your web method takes in the fXML as an integer attribute
return ws.SomeWebMethod(1);
You can use something like that:
var client = new WebClient();
var response = client.UploadValues("www.webservice.com", "POST", new NameValueCollection {{"fXML", "1"}});
using (var reader = new StringReader(Encoding.UTF8.GetString(response)))
{
var xml = XElement.Load(reader);
var value = xml.Element("somekey").Value;
Console.WriteLine("Some value: " + value);
}
Note I didn't have a chance to test this code, but it should work :)
It may also be worth adding that if you need to specifically use POST rather than SOAP then you can configure the web service to receive POST calls:
Check out the page on MSDN:
Configuration Options for XML Web Services Created Using ASP.NET

Categories

Resources