I'm using System.Net.Http.HttpClient to call some API.
It works correctly in UWP
It fails in WASM with the error : "Operation is not supported on this platform."
Stack trace show this is System.Net.WebProxy.CreateDefaultProxy() that fails.
What is the most universal way to do API call?
Currently, the best way to handle this is to set the default handler to Uno's WasmHttpHandler, as follows:
var httpMessageHandler = Type
.GetType("System.Net.Http.HttpClient, System.Net.Http")
.GetField("GetHttpMessageHandler",
BindingFlags.Static |
BindingFlags.NonPublic
);
httpMessageHandler.SetValue(
null,
(Func<HttpMessageHandler>)(() => new Uno.UI.Wasm.WasmHttpHandler())
);
Note that this does not override the default HttpHandler behavior, which means that if you use it explicitly, you'll get the same error.
Related
I added wcf services end point in asp.net core 2.0 to connected services and then I try to use that but with client there is only functions which ended with ..async
I don't want to use ...async.But there is no function without .async
What is problem with this?What should I do?
instead of using that
var response = SystemClient.SearchCountriesAsync(....
I want to use that
var response = SystemClient.SearchCountries(...
but it give that error
Error CS1061 'SystemClient' does not contain a definition for 'SearchCountries' and no extension method 'SearchCountries' accepting a first argument of type 'SystemClient' could be found (are you missing a using directive or an assembly reference?)
Your client does not expose synchronous method but that shouldn't be a problem for you.
Instead of asynchronously calling the method just do this:
response = SystemClient.SearchAirportsAsync(credentials, SystemHelperLanguageTypes.English, SystemHelperSearchTypes.CodeSearch, "ist").Result;
This will call the method synchronously as it will block the call. Check John Skeets answer here.
That being said I would recomend you use the async method that is provided. To support that you would have to change the Action signature to this:
public async Task<IActionResullt> Index()
{
SystemClient SystemClient = new SystemClient();
Credential credential = new Credential();
credential.UserName = "username";
credential.UserPassword = "****";
var response1 = await SystemClient.SearchCountriesAsync(credentials, SystemHelperLanguageTypes.English, SystemHelperSearchTypes.CodeSearch, "TR");
var response = await SystemClient.SearchAirportsAsync(credentials, SystemHelperLanguageTypes.English, SystemHelperSearchTypes.CodeSearch, "ist");
//Do whatever you do with those responses
ViewBag.Language = "ar";
return View();
}
There is a way to generate synchronous methods in your .NET core project in Visual Studio 2019.
Wizard that adds WCF web service reference to your .NET core project has an option Generate Synchronous Operations in the third step, Client Options:
Make sure you check it as it is unchecked by default.
I want to use BazingaGeocoderBundle to retrieve long and lat from postal code
https://github.com/geocoder-php/BazingaGeocoderBundle/blob/master/README.md
It was working when i used it without API_KEY, but of course soon stopped complaining about over-quota.
1) When i registered to “Google Maps Geocoding API”, and added API_KEY to :
C:\Bitnami\wampstack-5.5.30-0\sym_prog\proj2_27\vendor\willdurand\geocoder\src\Geocoder\Provider\GoogleMapsProvider.php
const ENDPOINT_URL_SSL = 'https://maps.googleapis.com/maps/api/geocode/json?address=%s&key=key';
const ENDPOINT_URL = 'https://maps.googleapis.com/maps/api/geocode/json?address=%s&key='; // just in case there is something wrong with private $useSsl = true; setting
If i try url from my browser - i am getting result with all coordinates:
If i try to use bazinga.geocoder, which was working perfectly previously (Of course if i try to use it without a key, i am getting over-quota error now).:
$addArr = $this->container
->get('bazinga_geocoder.geocoder')
->using('google_maps')
->geocode($addrArr[$random_addr_index]);
i am getting the error now:
[Geocoder\Exception\NoResultException]
Could not execute query http://maps.googleapis.com/maps/api/geocode/json?ad
dress=E16%201BH&key=AIzaSyB01WnF2o3M3GzUqn5UWZ_dVffssRrVXaQ
If i copy url to the browser - it lists result.
According documentation, Geocoder ships with the egeloen/http-adapter library by default: https://github.com/geocoder-php/Geocoder#http-adapters .
2)
If i configure adapter in config and services,
i am getting error: Invalid type for path "bazinga_geocoder.adapter". Expected array, but got string .
C:\Bitnami\wampstack-5.5.30-0\sym_prog\proj2_27\app\config\config.yml
bazinga_geocoder:
providers:
google_maps: ~
adapter: geocoder_adapter
C:\Bitnami\wampstack-5.5.30-0\sym_prog\proj2_27\app\config\services.yml
services:
geocoder_adapter:
class: Geocoder\HttpAdapter\CurlHttpAdapter
public: false
Where is my mistake? Does adapter here matters? What else i have to change in vendor\willdurand\geocoder\src\Geocoder\Provider\GoogleMapsProvider.php ?
3) How to configure an use correctly other suggested adapters?
* `BuzzHttpAdapter` to use [Buzz](https://github.com/kriswallsmith/Buzz), a lightweight PHP 5.3 library for issuing HTTP requests;
* `GuzzleHttpAdapter` to use [Guzzle](https://github.com/guzzle/guzzle), PHP 5.3+ HTTP client and framework for building RESTful web service clients;
* `SocketHttpAdapter` to use a [socket](http://www.php.net/manual/function.fsockopen.php);
* `ZendHttpAdapter` to use [Zend Http Client](http://framework.zend.com/manual/2.0/en/modules/zend.http.client.html).
This is when your address info is invalid.
In your case your address info:
http://maps.googleapis.com/maps/api/geocode/json?address=E16%201BH
Where is "address=E16%201BH" is the actual address as a URL encoded string.
As you can see this is not a valid address.
It should be something like this:
http://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway%2C+Mountain+View%2C+CA
To make your code more future proof, you should put a try catch around your encoding function.
try {
$addArr = $this->container
->get('bazinga_geocoder.geocoder')
->using('google_maps')
->geocode($addrArr[$random_addr_index]);
} catch (Exception $exception) {
$addArr = false;
}
I'm building RESTful service using Microsoft ASP.NET Web API.
My problem concerns HttpErrors that Web API throws back to user when something go wrong (e.g. 400 Bad Request or 404 Not Found).
The problem is, that I don't want to get serialized HttpError in response content, as it sometimes provides too much information, therefore it violates OWASP security rules, for example:
Request:
http://localhost/Service/api/something/555555555555555555555555555555555555555555555555555555555555555555555
As a response, I get 400 of course, but with following content information:
{
"$id": "1",
"Message": "The request is invalid.",
"MessageDetail": "The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'MyNamespaceAndMethodHere(Int32)' in 'Service.Controllers.MyController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter."
}
Something like this not only indicates that my WebService is based on ASP.NET WebAPI technology (which isn't that bad), but also it gives some information about my namespaces, method names, parameters, etc.
I tried to set IncludeErrorDetailPolicy in Global.asax
GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Never;
Yeah, that did somehow good, now the result doesn't contain MessageDetail section, but still, I don't want to get this HttpError at all.
I also built my custom DelegatingHandler, but it also affects 400s and 404s that I myself generate in controllers, which I don't want to happen.
My question is:
Is there any convinient way to get rid of serialized HttpError from response content? All I want user to get back for his bad requests is response code.
What about using a custom IHttpActionInvoker ?
Basically, you just have to send an empty HttpResponseMessage.
Here is a very basic example :
public class MyApiControllerActionInvoker : ApiControllerActionInvoker
{
public override Task<HttpResponseMessage> InvokeActionAsync(HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken)
{
var result = base.InvokeActionAsync(actionContext, cancellationToken);
if (result.Exception != null)
{
//Log critical error
Debug.WriteLine("unhandled Exception ");
return Task.Run<HttpResponseMessage>(() => new HttpResponseMessage(HttpStatusCode.InternalServerError));
}
else if (result.Result.StatusCode!= HttpStatusCode.OK)
{
//Log critical error
Debug.WriteLine("invalid response status");
return Task.Run<HttpResponseMessage>(() => new HttpResponseMessage(result.Result.StatusCode));
}
return result;
}
}
In Global.asax
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpActionInvoker), new MyApiControllerActionInvoker());
One other important thing you could do, not related to Web Api, is to remove excessive asp.net & IIS HTTP headers. Here is a good explanation.
I believe your approach of using the message handler is correct because regardless of the component in the Web API pipeline that sets the status code to 4xx, message handler can clear out response body. However, you do want to differentiate between the ones you explicitly set versus the ones set by the other components. Here is my suggestion and I admit it is a bit hacky. If you don't get any other better solution, give this a try.
In your ApiController classes, when you throw a HttpResponseException, set a flag in request properties, like so.
Request.Properties["myexception"] = true;
throw new HttpResponseException(...);
In the message handler, check for the property and do not clear the response body, if the property is set.
var response = await base.SendAsync(request, cancellationToken);
if((int)response.StatusCode > 399 && !request.Properties.Any(p => p.Key == "myException"))
response.Content = null;
return response;
You can package this a bit nicely by adding an extension method to HttpRequestMessage so that neither the ApiController nor the message handler knows anything about the hard-coded string "myException" that I use above.
Use EasyTracker:<bool name="ga_reportUncaughtExceptions">true</bool>
Ues ExceptionReporter:
UncaughtExceptionHandler myHandler = new ExceptionReporter(
myTracker, // Currently used Tracker.
GoogleAnalytics.getInstance(), // GoogleAnalytics singleton.
Thread.getDefaultUncaughtExceptionHandler()); // Current default uncaught exception handler.
Thread.setDefaultUncaughtExceptionHandler(myHandler); // Make myHandler the new default uncaught exception handler.
I can get other data,like event ,page,but I can not get any data of crash and Exception.I have set some uncatch exception and crashs in my program.
if you look in the API doc:
ExceptionReporter(Tracker tracker, ServiceManager serviceManager, java.lang.Thread.UncaughtExceptionHandler originalHandler)
GoogleAnalytics does not implement the ServiceManager interface.... luckily GAServiceManager does. Thus if you change:
GoogleAnalytics.getInstance()
to:
GAServiceManager.getInstance()
It works for me
I'm attempting to do something using Silex (which uses the Symfony routing component - so the answer may be applicable to Symfony as well)
I am adding Silex to a legacy application to provide routing but I need to respect the existing applications default implementation for loading files (which is simply to load the file from the file system form the URL specified).
edit: for clarification:
Existing file is loaded from the file system, as an include within an parent template, after a series of bootstrapping calls have been made.
What I'm finding is that in the absence of a defined route to match the legacy pages, Silex is throwing an exception.
I really need a way to provide a default (fallback) mechanism for handling those legacy pages - but my pattern has to match the entire url (not just one fragment).
Is this possible?
// Include Silex for routing
require_once(CLASS_PATH . 'Silex/silex.phar');
// Init Silex
$app = new Silex\Application();
// route for new code
// matches for new restful interface (like /category/add/mynewcategory)
$app->match('/category/{action}/{name}/', function($action, $name){
//do RESTFUL things
});
// route for legacy code (If I leave this out then Silex
// throws an exception beacuse it hasn't matched any routes
$app->match('{match_the_entire_url_including_slashes}', function($match_the_entire_url_including_slashes){
//do legacy stuff
});
$app->run();
This must be a common use case. I'm trying to provide a way to have a RESTFUL interface alongside legacy code (load /myfolder/mysubfolder/my_php_script.php)
I found the answer within the symfony cookbook...
http://symfony.com/doc/2.0/cookbook/routing/slash_in_parameter.html
$app->match('{url}', function($url){
//do legacy stuff
})->assert('url', '.+');
You can use the error handling, with something like that :
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
$app->error(function (\Exception $e) use ($app) {
if ($e instanceof NotFoundHttpException) {
return new Response('The requested page could not be found. '.$app['request']->getRequestUri(), 404);
}
$code = ($e instanceof HttpException) ? $e->getStatusCode() : 500;
return new Response('We are sorry, but something went terribly wrong.', $code);
});