Does anyone knows of a way to set or read the 'Date' HTTP header in an HTTP GET request on Windows Phone 8?
I need to be able to set the value of the Date header or at least read the value that will actually be sent in the request.
I have tried with something like:
var web_request = HttpWebRequest.CreateHttp(url);
web_request.Headers["Date"] = the_date;
But this produces an exception at run time:
System.ArgumentException: The 'Date' header must be modified using the appropriate property or method.
There's sample code here with HttpClient but this is apparently not available under Windows Phone 8:
How do you set the Content-Type header for an HttpClient request?
I have tried reading the date as well but after:
var web_request = HttpWebRequest.CreateHttp(url);
The date does not seem to be set yet.
That worked well after adding "Microsoft HTTP Client Libraries".
However there is still a problem in this library on WindowsPhone Platform.
PROBLEM:
I have a scenario where i want to add a "Date" header in a specific format, so i used
string customDate = "11/29/2013 7:46:25"
DefaultRequestHeaders.TryAddWithoutValidation("Date", customDate);
the above line adds the "Date" header, that means it does not throw any exception, but when i checked in fidler there is no "Date" header added. The same code works well in Windows8 store apps.
Looks like there is a bug in "Microsoft HTTP Client Libraries" for WindowsPhone8 platform.
By using "Microsoft HTTP Client Libraries" for Date header works well and good if Date is of DateTime object, however if i want to assign a value to Date header in a specific format as mentioned in earlier post then it does not get added.
Its a header with built-in support that you need to set/get explicitly;
web_request.Date = DateTime.UtcNow;
(Its default is 01/01/0001 00:00:00 which is not sent in the request)
The problem with:
web_request.Date
is that there is no "Date" property in the Windows Phone 8 version of HttpWebRequest.
See: http://social.msdn.microsoft.com/Forums/windowsapps/en-US/5738e95a-5afe-4a49-929d-b51490a5480b/httpwebrequest-date-property-missing
In this link it is suggested to use HttpClient and HttpRequestMessage. Example:
HttpClient client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url);
request.Headers.Date = DateTime.Now.Subtract(new TimeSpan(10, 0, 0));
HttpResponseMessage response = client.SendAsync(request).Result;
string resultCode = response.StatusCode.ToString();
I was stuck because HttpClient and HttpRequestMessage seem not to be available for Windows Phone 8 either. But it is possible to add them:
In Visual Studio (Express) 2012 for Windows Phone:
TOOLS -> Library Package Manager -> Manage NuGet Packages for Solution...
Then search for "Microsoft HTTP Client Libraries" and install it.
After that System.Net.Http is available and the HttpClient solution can be used.
Related
I'm trying to connect my ASP.NET Core 3.1 web app with Yahoo. To do this, I have to set up Authorization with OAuth. I have followed a few different guides, including:
https://developer.yahoo.com/oauth2/guide/openid_connect/getting_started.html
https://www.yogihosting.com/implementing-yahoo-oauth-2-0-in-csharp-and-asp-net/
I have set up my app in Yahoo, with the configuration found in the below picture:
I then have my code set up to send the authorization request to Yahoo with the following code:
public void YahooAuth()
{
string id = configuration["YahooClientId"];
string returnUrl = "https://www.fantasysimmer.com/FootballSimulator/Sim";
string url = $"https://api.login.yahoo.com/oauth2/request_auth?client_id={id}--&response_type=code&redirect_uri={returnUrl}";
Response.Redirect(url);
}
When this code is ran however, I get an error page with a message "Developers: Please specify a valid client and submit again.", and the URL displays:
https://api.login.yahoo.com/oauth2/error?client_id={Client_ID}--&error=unauthorized_client&error_description=invalid+client+id
I double and triple checked the Client ID, and the client ID in the URL is the same as in my Yahoo App's profile. I'm wondering now, is there an extra step that I missed in registering my app, or is there something wrong with my code?
Edit: Progress is made! The dashes after the client id must have been part of the example, or otherwise were an error. When I removed that, I started getting a new error, saying to enter in a valid request. It had something to do with my return url, because replacing that with 'oob' made it go through.
So there were two errors. The first was that the "--" after the client id were not supposed to be there. I'm not sure why in yahoo's example they have them there, but they aren't needed. The second reason is that my return uri was capitalized in my code, but not capitalized in my app settings. Now it works!
Last time we tested our application was on Tuesday, it was working well.
Today morning a long wait and timeout received from Microsoft when sending DETECT request with binary data in body. Nothing has changed between in our application.
I tested and my keys are okay (when they are not, we receive an answer but not 200, not a timeout).
When I try to DETECT using an URL, it is working (proper content-type and body of course)
Did anyone noticed the same, or using the API differently?
HttpClient client = HttpClientBuilder.create().build();
HttpPost request = new HttpPost("https://westeurope.api.cognitive.microsoft.com/face/v1.0/detect?returnFaceLandmarks=false&returnFaceId=true");
request.addHeader("Ocp-Apim-Subscription-Key", MY_KEY);
request.addHeader("Content-Type", "application/octet-stream");
HttpEntity entity = new ByteArrayEntity(Base64.getDecoder().decode(base64));
request.setEntity(entity);
response = client.execute(request);
It seems it was not a problem at out side. Suddenly it started to work...Hopefully will stay this way.
I need to make calls to a rest API service via BizTalk Send adapter. The API simply uses a token in the header for authentication/authorization. I have tested this in a C# console app using httpclient and it works fine:
string apiUrl = "https://api.site.com/endpoint/<method>?";
string dateFormat = "dateFormat = 2017-05-01T00:00:00";
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("token", "<token>");
client.DefaultRequestHeaders.Add("Accept", "application/json");
string finalurl = apiUrl + dateFormat;
HttpResponseMessage resp = await client.GetAsync(finalurl);
if (resp.IsSuccessStatusCode)
{
string result = await resp.Content.ReadAsStringAsync();
var rootresult = JsonConvert.DeserializeObject<jobList>(result);
return rootresult;
}
else
{
return null;
}
}
however I want to use BizTalk to make the call and handle the response.
I have tried using the wcf-http adapter, selecting 'Transport' for security (it is an https site so security is required(?)) with no credential type specified and placed the header with the token in the 'messages' tab of the adapter configuration. This fails though with the exception: System.IO.IOException: Authentication failed because the remote party has closed the transport stream.
I have tried googling for this specific scenario and cannot find a solution. I did find this article with suggestions for OAUth handling but I'm surprised that even with BizTalk 2016 I still have to create a custom assembly for something so simple.
Does anyone know how this might be done in the wcf-http send adapter?
Yes, you have to write a custom Endpoint Behaviour and add it to the send port. In fact with the WCF-WebHttp adapter even Basic Auth doesn't work so I'm currently writing an Endpoint Behaviour to address this.
One of the issues with OAuth, is that there isn't one standard that everyone follows, so far I've had to write 2 different OAuth behaviours as they have implemented things differently. One using a secret and time stamp hashed to has to get a token, and the other using Basic Auth to get a token. Also one of them you could get multiple tokens using the same creds, whereas the other would expire the old token straight away.
Another thing I've had to write a custom behaviour for is which version of TLS the end points expects as by default BizTalk 2013 R2 tries TLS 1.0, and then will fail if the web site does not allow it.
You can feedback to Microsoft that you wish to have this feature by voting on Add support for OAuth 2.0 / OpenID Connect authentication
Maybe someone will open source their solution. See Announcement: BizTalk Server embrace open source!
Figured it out. I should have used the 'Certificate' for client credential type.
I just had to:
Add token in the Outbound HTTP Headers box in the Messages tab and select 'Transport' security and 'Certificate' for Transport client credential type.
Downloaded the certificate from the API's website via the browser (manually) and installed it on the local servers certificate store.
I then selected that certificate and thumbprint in the corresponding fields in the adapter via the 'browse' buttons (had to scroll through the available certificates and select the API/website certificate I was trying to connect to).
I discovered this on accident when I had Fiddler running and set the adapter proxy setting to the local Fiddler address (http://localhost:8888). I realized that since Fiddler negotiates the TLS connection/certificate (I enabled tls1.2 in fiddler) to the remote server, messages were able to get through but not directly between the adapter and the remote API server (when Fiddler WASN'T running).
I am running ASP.Net 4.5, but using a very old version of the PayPal SOAP api. The reference is to paypal_base.dll with a reported version of 4.3.1.0. The code that calls the API has "using" statements that reference:
com.paypal.sdk.services
com.paypal.soap.api.
I have verified at the point where the call to the PayPal api is made, that this value
System.Net.ServicePointManager.SecurityProtocol
includes both ssl3 and tls1.2.
I am pointing at the "sandbox" mode.
But when the setExpressCheckout call is made, I get a runtime exception that says:
The request was aborted: Could not create SSL/TLS secure channel.
I have downloaded the PayPal API Samples project and using the same sandbox credentials, it works. Looking in Fiddler, the calls are nearly identical except the samples API call goes to api-3t.sandbox.paypal.com, while my code goes to api-aa.sandbox.paypal.com, but according to the documentation on TLS 1.2 readyness, both apis should work. I don't see anywhere in either API to set the endpoint other than switching between "live" and "sandbox".
In the fiddler response, both show:
"A SSLv3-compatible ServerHello handshake was found. Fiddler extracted the parameters below.
Version: 3.3 (TLS/1.2)"
And the responses are identical except for the "random" parameter. So the old API call is using TLS 1.2
My code and the Samples API code are only slightly different, the sample uses:
SetExpressCheckoutRequestType request = new SetExpressCheckoutRequestType();
populateRequestObject(request); //populate request data
SetExpressCheckoutReq wrapper = new SetExpressCheckoutReq();
wrapper.SetExpressCheckoutRequest = request;
Dictionary<string, string> configurationMap = Configuration.GetAcctAndConfig(); //set merchant config
PayPalAPIInterfaceServiceService service = new PayPalAPIInterfaceServiceService(configurationMap);
SetExpressCheckoutResponseType setECResponse = service.SetExpressCheckout(wrapper); //make the call
Where my (again, very old code looks like this):
CallerServices caller = new CallerServices();
caller.APIProfile = SetProfile.ApplicationProfile; //set merchant config
SetExpressCheckoutRequestType pp_request = new SetExpressCheckoutRequestType();
// Create the request details object
pp_request.SetExpressCheckoutRequestDetails = new SetExpressCheckoutRequestDetailsType();
pp_request.SetExpressCheckoutRequestDetails.PaymentAction = paymentAction;
pp_request.SetExpressCheckoutRequestDetails.PaymentActionSpecified = true;
pp_request.SetExpressCheckoutRequestDetails.OrderTotal = new BasicAmountType();
pp_request.SetExpressCheckoutRequestDetails.OrderTotal.currencyID = currencyCodeType;
pp_request.SetExpressCheckoutRequestDetails.OrderTotal.Value = paymentAmount;
pp_request.SetExpressCheckoutRequestDetails.CancelURL = cancelURL;
pp_request.SetExpressCheckoutRequestDetails.ReturnURL = returnURL;
return (SetExpressCheckoutResponseType) caller.Call("SetExpressCheckout", pp_request); //do the call
The sample code works, my code throws the SSL/TLS error. I tried upgrading to the latest SDK, but so much has changed, it will be quite a large effort to migrate all that code.
From fiddler, it seems to be using TLS 1.2 even with the old API, but I get a runtime exception about the SSL/TLS connection. Is it because of the different endpoint? Is the old API just too old?
Thanks in advance for any help - I would love to avoid migrating all that ancient code!.
EDIT: I should mention I am using the UserName/Password/Signature credentials, not certificate based credentials.
As TLS1.2 is supported in .Net4.5 but it is not a default protocol. you need to opt-in to use it. The following code will make TLS 1.2 default, make sure to execute it before making a connection to secured resource:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
I was having a similar issue, with a PP Sandbox credentialing "HttpWebRequest" in C# Web Application 4.5, receiving the following error: "You must write ContentLength bytes to the request stream before calling [Begin]GetResponse".
I read this Q/A and applied the ServicePointManager reference from above answer - as the first line in my HttpWebRequest call method, and it worked. Thanks to all.
FYI, the example code I am building is from //learn.microsoft.com, "Getting Started with ASP.NET 4.5 Web Forms and Visual Studio 2017".
hi friends i'm a newbie in blackberry programming and have managed to make a small application... The application downloads an xml file through http and parses it and displays it on the screen... now the problem is that though it works fine on my simulator... the client complains that he's getting an error in connection if he connects it through 3G... do i need to add anything other than the following...
// Build a document based on the XML file.
url = <my clients url file>;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
hc = (HttpConnection)Connector.open(url+";deviceside=true");
hc.setRequestMethod(HttpConnection.GET);
InputStream inputStream = hc.openInputStream();
hc.getFile();
Document document = builder.parse(inputStream);
hc.close();
inputStream.close();
Do i need to add anything to make it download http content through 3G also??
Specifying "deviceside=true" requires the device have the APN correctly configured, or you include APN specification in the URL. Have a look at this video.
You need to be able to detect what sort of connection the device is using as was said above deviceside=true works only for APN. If you want to just test it out try using
;deviceside=false //for mds
;deviceside=false;ConnectionType=mds-public //for bis-b
;interface=wifi //for wifi