VFP and .NET Interop
wwDotNetBridge with await syntax
Gravatar is a globally recognized avatar based on your email address. wwDotNetBridge with await syntax
  Vilciu Constantin
  All
  Oct 7, 2017 @ 09:42am

Hi, Rick.

Please teach me, if you want, to convert the following c # code into FoxPro.

//Common testing requirement. If you are consuming an API in a sandbox/test region, 
//uncomment this line of code ONLY for non production uses.
//System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
//Be sure to run "Install-Package Microsoft.Net.Http" from your nuget command line.

using System;
using System.Net.Http;

var baseAddress = new Uri("https://private-anon-6ee8a25cb2-openapiro.apiary-mock.com/");
using (var httpClient = new HttpClient{ BaseAddress = baseAddress })
  httpClient.DefaultRequestHeaders.TryAddWithoutValidation("x-api-key", "{api_key}");
  using(var response = await httpClient.GetAsync("undefined"))
  {
         string responseData = await response.Content.ReadAsStringAsync();
  }
} 

I'm confused with the "await" syntax, I do not know how to translate it.

loBridge=NewObject('wwDotNetBridge', 'wwDotNetBridge.prg', '', 'V4')
lcURL="https://private-anon-6ee8a25cb2-openapiro.apiary-mock.com/"

*** Load an assembly from disk
loBridge.LoadAssembly("System.Net.Http")

*** Create an instance of a class - note: No COM registration
loHttpClient=loBridge.CreateInstance("System.Net.Http.HttpClient")

loURI=loBridge.CreateInstance('System.Uri', lcUrl)
loBridge.SetProperty(loHttpClient,"BaseAddress", loURI)

*httpClient.DefaultRequestHeaders.TryAddWithoutValidation("x-api-key", "{api_key}");
lcOpenAPIKey="6VdcC3Z_eXBbZsBi7h_rqQr9AQXYEbRUP3xo4pwu6LANrs8_1A"	&&vicos_2004@yahoo.com

loBridge.InvokeMethod(loHttpClient, "DefaultRequestHeaders.TryAddWithoutValidation", "x-api-key", lcOpenAPIKey)

loResponse=loBridge.InvokeMethod(loHttpClient, "GetAsync", "undefined")

lcResponseData=loBridge.InvokeMethod(loResponse, "Content.ReadAsStringAsync()")
?lcResponseData
?loBridge.cERRORMSG

Error: OLE IDispatch exception code 0 from wwDotNetBridge: Index was outside the bounds of the array...

Probably because I did not use the syntax "await".

Thank you in advance.

Gravatar is a globally recognized avatar based on your email address. re: wwDotNetBridge with await syntax
  Rick Strahl
  Vilciu Constantin
  Oct 7, 2017 @ 02:40pm

Simple answer don't use HttpClient(). There are plenty of other options to make HTTP calls. You can use wwHttp, or if you want to use .NET code use WebClient.

Call async code over COM is not possible I believe unless you create a .NET wrapper and return the result.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: wwDotNetBridge with await syntax
  Vilciu Constantin
  Rick Strahl
  Oct 10, 2017 @ 06:06am

Can guide me how to create a .Net wrapper?

Regards.

Gravatar is a globally recognized avatar based on your email address. re: wwDotNetBridge with await syntax
  Rick Strahl
  Vilciu Constantin
  Oct 10, 2017 @ 02:11pm

Take a look at the White Paper.

Again if you're trying to call HttpClient you're probably doing it wrong - there are many many other options to do this that are easier to call from FoxPro including WebClient in .NET or wwHttp with native FoxPro.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: wwDotNetBridge with await syntax
  Rick Strahl
  Vilciu Constantin
  Oct 11, 2017 @ 02:11am

So I took another look at this - turns out wwDotnetBridge can call Async methods in .NET.

The following is a call to WebClient.DownloadTaskAsync() (Api) which is an async method:

CLEAR
do wwDotNetBridge
LOCAL loBridge as wwDotNetBridge
loBridge = CreateObject("wwDotNetBridge","V4")

loClient = loBridge.CreateInstance("System.Net.WebClient")
loTask = loBridge.InvokeMethod(loClient,"DownloadStringTaskAsync","https://west-wind.com")
? loTask   && returns immedately
lcHtml = loBridge.GetProperty(loTask,"Result")
? lcHtml

This works.

Note that you have to call the async method indirectly with InvokeMethod() and you have to retrieve the value from the Task<T> result using GetProperty() because the value is comes from a generic property assignment.

But - again I think this is a bad idea. While this makes the async call in the background, the .Result will make your code wait for completion. However, you can continue doing other stuff after you've retrieved loTask and retrieve .Result.

Of course if you're using WebClient you probably would be much better off just using the DownloadString() (or other download) method.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: wwDotNetBridge with await syntax
  Rick Strahl
  Vilciu Constantin
  Oct 11, 2017 @ 12:19pm

I've also written up a blog post with more details on how async/await works in .NET and how we can call these types of methods from FoxPro.

+++ Rick ---

© 1996-2019