I write an app on Xamarin.Android. Directions API works perfectly when debugging on emulator. But it doesn't work when testing on a physical device. I suppose the problem can be in http request. Is somebody familiar with such a problem?
public async Task<string> GetDirectionJsonAsync(LatLng location, LatLng destLocation, string mapkey)
{
// Origin of route
string str_origin = "origin=" + location.Latitude.ToString() + "," + location.Longitude.ToString();
// Destination of route
string str_destination = "destination=" + destLocation.Latitude.ToString() + "," + destLocation.Longitude.ToString();
// Mode
string mode = "mode=driving";
string parameters = str_origin + "&" + str_destination + "&" + mode + "&key=" + mapkey;
// Output
string output = "json";
string url = "https://maps.googleapis.com/maps/api/directions/" + output + "?" + parameters;
var handler = new HttpClientHandler();
HttpClient client = new HttpClient(handler);
string jsonString = await client.GetStringAsync(url);
return jsonString;
}
Related
I am trying to integrated Google Calendar Integration to my web site. Everything run on local host is perfect. But when I publish it in to domain it give me some error.
This bt.mypage.kr page can’t be foundNo webpage was found for the web
address:
http://bt.mypage.kr/o/oauth2/v2/auth?scope=https://www.googleapis.com/auth/calendar+https://www.googleapis.com/auth/calendar.events&access_type=online&include_granted_scopes=true&response_type=code&state=state_parameter_passthrough_value&redirect_uri=http://bt.mypage.kr/Schedule/UI/oauth2callback&client_id=myclientid
My code some thing like this:
public ActionResult AuthRedirect()
{
var url = "http://" + Request.Host;
sting redirect_uri = url + "/Schedule/UI/oauth2callback"
GoogleParram gpr = new GoogleParram(url);
string rerectUrl = "https://accounts.google.com/o/oauth2/v2/auth?" +
"scope=https://www.googleapis.com/auth/calendar+https://www.googleapis.com/auth/calendar.events&" +
"access_type=online&" +
"include_granted_scopes=true&" +
"response_type=code&" +
"state=state_parameter_passthrough_value&" +
"redirect_uri=" + url + "/Schedule/UI/oauth2callback&" +
"client_id=" + gpr.client_id;
return Redirect(rerectUrl);
}
public void oauth2callback(string code, string error, string state)
{
if (string.IsNullOrWhiteSpace(error))
{
this.GetTokens(code);
}
}
public IActionResult GetTokens(string code)
{
var url = "http://" + Request.Host;
GoogleParram gpr = new GoogleParram(url);
var request = new RestRequest();
request.AddQueryParameter("client_id", gpr.client_id);
request.AddQueryParameter("client_secret", gpr.client_secret);
request.AddQueryParameter("code", code);
request.AddQueryParameter("grant_type", "authorization_code");
request.AddQueryParameter("redirect_uri", url + "/Schedule/UI/oauth2callback&");
RestClient restClient = new RestClient(gpr.token_uri);
var response = restClient.Post(request);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
gpr.WriteToken(response.Content);
return RedirectToAction("Calendar");
}
return RedirectToAction("Calendar");
}
My Credentials
I hope anybody knows how to solve. Bundle of Thanks in advance.
MVC web app calling methods in a MVC web api.
I have an async method which executes another async method - GetMultiSelections(...).
Both call out to a web api.
They work fine.
However, I added in some new code - the foreach after the 1st method - GetMultiSelections(...).
I encountered an error. So I now want to call another web api method to write the error to a log. It's a non-async method that does not return anything as I don't want anything coming back. (or should I?)
I do this in the 1st Catch. It executes the non-async method but does not go into the web api. I step threw it but it never actually goes into the web api method. I have a break point in the web api and it does not get there.
Is the async preventing it? If so, how to I get the non-async to be executed?
In the non-async method and does the call to the web api - just does not get in there:
The api method - it does not get here:
Returned from the non-async method - and throws the error as expected:
The async method which executes another async method. The both do a call to the web api.:
[HttpGet]
public async Task<ActionResult> GetUserProfile()
{
UserProfileForMaintVM userProfileForMaintVM = new UserProfileForMaintVM();
try
{
List<UserProfileHoldMulti> userProfileHoldMulti = new List<UserProfileHoldMulti>();
// Get all the user's multi-selections and the ones he/she did not select.
userProfileHoldMulti = await GetMultiSelections(Session["UserName"].ToString(), Convert.ToInt32(Session["UserId"]));
foreach (var hold in userProfileHoldMulti)
{
switch (hold.ProfileCategoryId)
{
case 25:
// Instantiate a new UserProfileMulti25.
UserProfileMulti25 userProfileMulti25 = new UserProfileMulti25
{
SelectionId = hold.SelectionId,
ProfileCategoryId = hold.ProfileCategoryId,
Description = hold.Description,
SelectedSwitch = hold.SelectedSwitch
};
// Add the multi list to the model's multi list.
userProfileForMaintVM.UserProfileMultiList25.Add(userProfileMulti25);
break;
}
}
}
catch (Exception ex)
{
// Call the web api to process the error.
ProcessClientError(Session["UserName"].ToString(), ex.Message, "From method: GetUserProfile. processing multi-selections");
throw;
}
if ((string)#Session["HasProfileSwitch"] == "False")
{
return View("UserProfileMaint", userProfileForMaintVM);
}
else
{
try
{
string hostName = Dns.GetHostName();
string myIpAddress = Dns.GetHostEntry(hostName).AddressList[2].ToString();
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:56224");
string restOfUrl = "/api/profileandblog/getuserprofile/" + Session["UserName"] + "/" + myIpAddress + "/" + Session["UserId"];
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage result = await client.GetAsync(restOfUrl);
if (result.IsSuccessStatusCode)
{
var userResponse = result.Content.ReadAsStringAsync().Result;
userProfileForMaintVM.UserProfileSingleVM = JsonConvert.DeserializeObject<UserProfileSingleVM>(userResponse);
}
else
{
ViewBag.errormessage = "Server error on getting the active userProflie. UserId: " + Session["UserId"] + ". Method: 'GetUserProfile'. Please contact the administrator.";
}
return View("UserProfileMaint", userProfileForMaintVM);
}
}
catch (Exception)
{
throw;
}
}
}
The non-async method:
public void ProcessClientError(string userName, string errorMessage, string additionalInfo)
{
try
{
string hostName = Dns.GetHostName();
string myIpAddress = Dns.GetHostEntry(hostName).AddressList[2].ToString();
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:56224");
string restOfUrl = "/api/profileandblog/processclienterror/" + Session["UserName"] + "/" + errorMessage + additionalInfo + myIpAddress + "/";
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.GetAsync(restOfUrl);
}
}
catch (Exception)
{
throw;
}
}
GetAsync/PostAsync doesn't necessarily need to call an async method. The GetAsync/PostAsync are the actual async methods wherein once it is called, you have the option to wait for it to finish.
The error I'm seeing is you're calling the webapi with GetAsync but in your screenshot the web method ProcessClientError is [HttpPost].
Change ProcessClientError data annotation to [HttpGet].
Hmm, upon checking again, the url you're trying to access might not match the one you provided in your route. It's missing some slashes /.
your current:
string restOfUrl = "/api/profileandblog/processclienterror/" + Session["UserName"] + "/" + errorMessage + additionalInfo + myIpAddress + "/";
possible fix:
string restOfUrl = "/api/profileandblog/processclienterror/" + Session["UserName"] + "/" + errorMessage + "/" + additionalInfo + "/" + myIpAddress + "/";
If that still doesnt work, try to url encode the parameters with slashes /.
string restOfUrl = "/api/profileandblog/processclienterror/" + Session["UserName"] + "/" + errorMessage + "/" + additionalInfo + "/" + Url.Encode(myIpAddress) + "/";
We are building a data integration platform to connect to Salesforce.
Would like to know if there is any documentation to create a connected app programmatically using APIs. I see lot of documentation for creating connected apps via UI but not through API.
You can create Connected Apps through the Metadata API, like any other Salesforce metadata.
The easiest way to do this is to build the Connected App in a Salesforce org and then extract it with a Metadata API client (SFDX, Workbench, CumulusCI, Ant...). Excise the Consumer Key from the metadata, and you'll then be able to deploy that Connected App cleanly into another org.
Note, though, that this is rarely necessary. Connected Apps are global metadata: you typically maintain your Connected App in a single org that you control, and it's then available everywhere. I've really only seen the need to deploy Connected Apps when a different one is needed in each subscriber org.
This code creates connected app.
MetadataService.MetadataPort service = createService();
MetadataService.ConnectedApp connectedApp = new MetadataService.ConnectedApp();
connectedApp.label = 'Test 005';
connectedApp.fullName = 'Test_005';
connectedApp.contactEmail = 'email#email.com';
MetadataService.ConnectedAppOauthConfig oauthConfig = new
MetadataService.ConnectedAppOauthConfig();
oauthConfig.consumerKey = 'yourConsumerKey';
oauthConfig.consumerSecret = 'yourConsumerSecret';
oauthConfig.scopes = new List<String>{'Basic', 'Api', 'Web', 'Full'};
oauthConfig.callbackUrl = 'https://www.google.com/';
connectedApp.oauthConfig = oauthConfig;
List<MetadataService.SaveResult> results = service.createMetadata(new
MetadataService.Metadata[] { connectedApp });
If you don't want to use Metadata API library, you could use the following snippet of code
private static String getSoapBodyXml(String endpoint, String name) {
return ''
+ '<?xml version="1.0" encoding="utf-8"?>'
+ '<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
+ '<env:Header>'
+ '<urn:SessionHeader xmlns:urn="http://soap.sforce.com/2006/04/metadata">'
+ '<urn:sessionId>' + userInfo.getSessionId() + '</urn:sessionId>'
+ '</urn:SessionHeader>'
+ '</env:Header>'
+ '<env:Body>'
+ '<createMetadata xmlns="http://soap.sforce.com/2006/04/metadata">'
+ '<metadata xsi:type="ConnectedApp">'
+ '<fullName>' + name + String.valueOf(DateTime.now().getTime()).right(4) + '</fullName>'
+ '<label>' + name + String.valueOf(DateTime.now().getTime()).right(4) + '</label>'
+ '<contactEmail>julfy#i.ua</contactEmail>'
+ '<oauthConfig>'+
+ '<callbackUrl>' + endpoint + '</callbackUrl>'
+ '<scopes>Full</scopes>'
+ '<scopes>RefreshToken</scopes>'
+ '</oauthConfig>'
+ '</metadata>'
+ '</createMetadata>'
+ '</env:Body>'
+ '</env:Envelope>'
;
}
public static HttpResponse add(String endpoint, String name) {
HttpRequest req = new HttpRequest();
req.setEndpoint(URL.getOrgDomainUrl().toExternalForm() + '/services/Soap/m/50.0');
req.setMethod('POST');
req.setHeader('Content-Type', 'text/xml');
req.setHeader('SOAPAction', '""');
req.setBody(getSoapBodyXml(endpoint, name));
HttpResponse r = new Http().send(req);
System.debug('add getBody: ' + r.getBody());
System.debug('add getStatus: ' + r.getStatus());
System.debug('add getStatusCode: ' + r.getStatusCode());
val(r);
return r;
}
private static void val(HttpResponse r) {
System.debug('success? ' + r.getBody().contains('<success>true</success>'));
if (!r.getBody().contains('<success>true</success>')) {
throw new UnexpectedException(r.getBody().substringBetween('<statusCode>', '</statusCode>') + ': ' + r.getBody().substringBetween('<message>', '</message>'));
}
}
public static HttpResponse deploy(Integer i) {
return add(
'https://google.com',
'DeployedApp' + i
);
}
I have used following code for file reading and writing.
private void StorePuzzleData ()
{
FileInfo fileInfo = new FileInfo (Application.persistentDataPath + "\\" + difficultyLevel + puzzleId + ".txt");
if (fileInfo.Exists)
fileInfo.Delete ();
string fileData = string.Empty;
foreach (CellInformation cellInfo in cellInfoList)
fileData += cellInfo.RowIndex + "#" + cellInfo.ColIndex + "#" + cellInfo.number + "#" + cellInfo.CellColor + "#" + cellInfo.CellDisplayColor + "#" + (cellInfo.IsGroupComplete ? 1 : 0) + ",";
StreamWriter streamWriter = fileInfo.CreateText ();
streamWriter.WriteLine (fileData);
streamWriter.Close ();
DataStorage.StorePuzzleTimePassed (difficultyLevel, puzzleId, GameController.gamePlayTime);
}
private void ReadPuzzleData ()
{
// format: rownumber, colnumber, number, cellcolor, celldisplaycolor, isgroupcomplete
StreamReader streamReader = File.OpenText (Application.persistentDataPath + "\\" + difficultyLevel + puzzleId + ".txt");
string fileData = streamReader.ReadLine ();
}
But I am getting following error in actual iOS device running. This code working correct in iMac as well in android device.
Please give me some suggestion what changes I need to do to make this correct.
It seems you're using Windows-style paths in a Unix-like (Apple Mac OS) environment. Notice that on windows you have paths with a backslash like
C:\Users\Maxi\Desktop
On Unix-like system however something like
/var/mobile/Containers
You notice that in your faulty path you have mixed forward and backward slashes, which makes the path invalid.
/var/mobile/Containers/Data/Application/2.....\debutan1.txt
The correct way to always generate the correct path is to use the Path.Combine(string, string) function. This will combine two paths using the correct directory path seperator, which can also be seperatly accessed through Path.DirectorySeparatorChar.
So, in order to make your code correct, you would do
using System.IO; /* must be imported */
private void StorePuzzleData ()
{
FileInfo fileInfo = new FileInfo (Path.Combine(Application.persistentDataPath, difficultyLevel + puzzleId + ".txt"));
if (fileInfo.Exists)
fileInfo.Delete ();
string fileData = string.Empty;
foreach (CellInformation cellInfo in cellInfoList)
fileData += cellInfo.RowIndex + "#" + cellInfo.ColIndex + "#" + cellInfo.number + "#" + cellInfo.CellColor + "#" + cellInfo.CellDisplayColor + "#" + (cellInfo.IsGroupComplete ? 1 : 0) + ",";
StreamWriter streamWriter = fileInfo.CreateText ();
streamWriter.WriteLine (fileData);
streamWriter.Close ();
DataStorage.StorePuzzleTimePassed (difficultyLevel, puzzleId, GameController.gamePlayTime);
}
private void ReadPuzzleData ()
{
// format: rownumber, colnumber, number, cellcolor, celldisplaycolor, isgroupcomplete
StreamReader streamReader = File.OpenText (Path.Combine(Application.persistentDataPath, difficultyLevel + puzzleId + ".txt"));
string fileData = streamReader.ReadLine ();
}
If this still gives an "Access denied" error it must be because of filepermissions. Post the output of ls -la <thatpath> then.
I am trying to build a mini-webserver on an iPad inside an Adobe AIR application.
I am using the ServerSocket class to set up the webserver as shown by example at http://coenraets.org/blog/2010/07/creating-a-web-server-using-the-new-server-socket-api-in-air-2/.
I am trying to extend this by allowing the webserver to serve mp4 video files.
I have added the mimetype: mimeTypes[".mp4"] = "video/mp4";
but serving an mp4 to be played in a browser is not exactly the same as providing a html file.
Anyone can point me in the right direction for this? This is the code I currently have when the socket is responding:
private function webserverConnectionSocketDataHandler(evt:ProgressEvent):void{
try
{
var socket:Socket = evt.target as Socket;
var bytes:ByteArray = new ByteArray();
socket.readBytes(bytes);
var request:String = "" + bytes;
var filePath:String = request.substring(5, request.indexOf("HTTP/") - 1);
var file:File = File.applicationDirectory.resolvePath("AppStorage").resolvePath(filePath);
if (file.exists && !file.isDirectory)
{
//Range: bytes=0-131726
var offset:uint = 0;
var bytesRequested:uint = 0;
if(request.indexOf("Range: bytes=") >= 0){
offset = uint(request.split("Range: bytes=")[1].split("-")[0]);
bytesRequested = (request.split("Range: bytes=")[1].split("-")[1]);
}
if(bytesRequested == 0) bytesRequested = file.size;
var stream:FileStream = new FileStream();
stream.open( file, FileMode.READ );
var content:ByteArray = new ByteArray();
stream.readBytes(content, offset, bytesRequested);
stream.close();
if(bytesRequested != file.size){
socket.writeUTFBytes("HTTP/1.1 206 Partial Content\n");
socket.writeUTFBytes("Content-Type: " + getMimeType(filePath) + "\n\n");
socket.writeUTFBytes("Content-Range: " + offset + "-" + bytesRequested + "/" + file.size + "\n\n");
socket.writeUTFBytes("Content-Length: " + (bytesRequested-offset) + "\n\n");
socket.writeUTFBytes("Date: " + new Date().toLocaleTimeString() + "\n\n");
}else{
socket.writeUTFBytes("HTTP/1.1 200 OK\n");
socket.writeUTFBytes("Content-Type: " + getMimeType(filePath) + "\n\n");
socket.writeUTFBytes("Content-Length: " + file.size + "\n\n");
}
socket.writeBytes(content);
}
else
{
socket.writeUTFBytes("HTTP/1.1 404 Not Found\n");
socket.writeUTFBytes("Content-Type: text/html\n\n");
socket.writeUTFBytes("<html><body><h2>Page Not Found</h2></body></html>");
}
socket.flush();
socket.close();
}
catch (error:Error)
{
trace(error.message, "Error");
}
}
But that is not really working as expected. The goal is to be able to view an mp4 from inside my iPad application's AppStorage directory from inside my browser on PC. It works for html files, not for mp4.