Here is my code. It's been over a month I'm trying to add calendars in Outlook but nothing is working :( please help. The function AcquireTokenByAuthorizationCodeAsync never completes. And the token.Result is always null
string authority = ConfigurationManager.AppSettings["authority"];
string clientID = ConfigurationManager.AppSettings["clientID"];
Uri clientAppUri = new Uri(ConfigurationManager.AppSettings["clientAppUri"]);
string serverName = ConfigurationManager.AppSettings["serverName"];
var code = Request.Params["code"];
AuthenticationContext ac = new AuthenticationContext(authority, true);
ClientCredential clcred = new ClientCredential(clientid, secretkey);
//ac = ac.AcquireToken(serverName, clientID, clientAppUri, PromptBehavior.Auto);
//string to = ac.AcquireToken(serverName, clientID, clientAppUri, PromptBehavior.Auto).AccessToken;
var token = ac.AcquireTokenByAuthorizationCodeAsync(code, new Uri("http://localhost:2694/GetAuthCode/Index/"), clcred, resource: "https://graph.microsoft.com/");
string newtoken = token.Result.AccessToken;
ExchangeService exchangeService = new ExchangeService(ExchangeVersion.Exchange2013);
exchangeService.Url = new Uri("https://outlook.office365.com/" + "ews/exchange.asmx");
exchangeService.TraceEnabled = true;
exchangeService.TraceFlags = TraceFlags.All;
exchangeService.Credentials = new OAuthCredentials(token.Result.AccessToken);
exchangeService.FindFolders(WellKnownFolderName.Root, new FolderView(10));
Appointment app = new Appointment(exchangeService);
app.Subject = "";
app.Body = "";
app.Location = "";
app.Start = DateTime.Now;
app.End = DateTime.Now.AddDays(1);
app.Save(SendInvitationsMode.SendToAllAndSaveCopy);
I have experienced this issue when I call the AcquireTokenByAuthorizationCodeAsync using result instead of using await key words and all these code was in a asynchronously controller in the MVC.
If you are in the same scenario, you can fix this issue by two ways:
1.Always using the async, await like code below:
public async System.Threading.Tasks.Task<ActionResult> About()
{
...
var result =await ac.AcquireTokenByAuthorizationCodeAsync(code, new Uri("http://localhost:2694/GetAuthCode/Index/"), clcred, resource: "https://graph.microsoft.com/");
var accessToken = result.AccessToken;
...
}
2.Use the synchronization controller:
public void About()
{
...
var result =ac.AcquireTokenByAuthorizationCodeAsync(code, new Uri("http://localhost:2694/GetAuthCode/Index/"), clcred, resource: "https://graph.microsoft.com/").Result;
var accessToken = result.AccessToken;
...
}
Related
I've created a public Data Entity in dynamics with the following fields:
I keep getting a bad request response, but I'm not sure why.
I've tried to make a POST request in two ways:
1.
HireAction hireAction = new HireAction() { CompanyName = "DEMF", MovieId = "DEMF-000000014", HireActionStatus = "Created" };
string jsonMessage = JsonConvert.SerializeObject(hireAction);
using (HttpClient client = new HttpClient())
{
HttpRequestMessage requestMessage = new
HttpRequestMessage(HttpMethod.Post, "MyDynamicsEnvironmentName/data/HireActions?cross-company=true");
requestMessage.Content = new StringContent(jsonMessage, Encoding.UTF8, "application/json");
requestMessage.Headers.Add("Authorization", AuthResult.AuthorizationHeader);
HttpResponseMessage response = client.SendAsync(requestMessage).Result;
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
//Logic
}
}
var url = "MyDynamicsEnvironmentName/data/HireActions?cross-company=true";
var req = HttpWebRequest.Create(url);
req.Method = "POST";
req.ContentType = "application/json";
req.Headers["Authorization"] = AuthResult.AuthorizationHeader;
HireAction hireAction = new HireAction() { CompanyName = "DEMF", MovieId = "DEMF-000000014", HireActionId = "12345", HireActionStatus = "Created" };
var jsonSettings = new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.Local
};
var postString = "CompanyName='DEMF'" + "&MovieId='DEMF-000000014'" + "&HireActionId=132&HireActionStatus='Created'";
var data = JsonConvert.SerializeObject(postString, jsonSettings);
var bytes = Encoding.Default.GetBytes(postString);
var newStream = req.GetRequestStream();
newStream.Write(bytes, 0, bytes.Length);
newStream.Close();
using (var resp = req.GetResponse())
{
var results = new StreamReader(resp.GetResponseStream()).ReadToEnd();
}
Some keypoints:
-Of course you'd replace MyDynamicsEnvironmentName with the URL for the environment. The URL is correct and verified however, by the fact that GET requests do work
-The Authresult.AuthorizationHeader contains a valid token, also validated by working GET requests
As said before, both of these result in a bad request. Does someone know what is wrong or missing?
The code below gets a token which I then use to try and fetch some data from an API which is behind AzureAD authentication.
I get a token back, but when I use it to try and reach the API, I get "login to your account" in apiResponse.
What is wrong with my authorization?
var recoAadAppId = "xxxxxxxxxxxxxx";
var callerAadAppId = "xxxxxxxxxxxxxx";
var callerAadTenantId = "xxxxxxxxxxxxxx";
var token = await AcquireTokenWithSecret(callerAadAppId, callerAadTenantId, recoAadAppId);
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = AuthenticationHeaderValue.Parse(token.CreateAuthorizationHeader());
using (var response = await httpClient.GetAsync("https://redacted/app/rest/buildQueue"))
{
string apiResponse = await response.Content.ReadAsStringAsync();
}
public static Task<AuthenticationResult> AcquireTokenWithSecret(
string callerAadAppId, string callerTenantId, string recoAadAppId)
{
var secret = "mysecret";
var app = ConfidentialClientApplicationBuilder.Create(callerAadAppId).WithAuthority($"https://login.microsoftonline.com/{callerTenantId}").WithClientSecret(secret).Build();
var scopes = new[] { $"{recoAadAppId}/.default" };
return app.AcquireTokenForClient(scopes).ExecuteAsync(CancellationToken.None);
}
I am trying to refresh my listview when an item is removed from it, but every time it gives me this error:
System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: index.
Before updating the ObservableCollection, I do this:
Groups = new ObservableCollection<RequestGroups>();
And then I fill it with this:
var temp = (JArray)resultJson["data"];
JArray jarr = temp;
foreach (JObject contents in jarr.Children<JObject>())
{
Requests obj = new Requests();
obj.Id = (int)contents["id"];
Client c = new Client();
c.address = contents["address"].ToString();
c.phone = contents["phone"].ToString();
c.name = contents["user"].ToString();
obj.Client = c;
obj.Date = contents["date"].ToString();
obj.Duration = contents["duration"].ToString();
obj.DurationText = "Duración: "+contents["duration"].ToString()+"h";
obj.Price = "$" + contents["price"].ToString();
String[] cDate = obj.Date.Split(' ');
String cHour = cDate[1]+" "+cDate[2];
obj.Hour = cHour;
String[] date = cDate[0].Split('-');
String title = months[date[1]] + " " + date[0];
obj.Title = title;
bool flag = false;
foreach(RequestGroups rqG in Groups){
if(rqG.Title.Equals(title)){
rqG.Add(obj);
flag = true;
}
}
if(!flag){
RequestGroups rq = new RequestGroups(title, date[1] + "-" + date[0]);
rq.Add(obj);
Device.BeginInvokeOnMainThread(() =>
{
Groups.Add(rq);
});
}
}
This is where I remove the items:
private async Task UpdateRequest(int status,int idEvent)
{
HttpClient hTTPClient = new HttpClient();
var client = new HttpClient();
client.Timeout = TimeSpan.FromSeconds(60);
client.BaseAddress = new Uri(Utils.baseUrl);
Dictionary<string, string> dataToSend = new Dictionary<string, string>();
dataToSend.Add("session", Utils.loginKey);
dataToSend.Add("eventId", idEvent+"");
dataToSend.Add("status", status.ToString());
string jsonData = Newtonsoft.Json.JsonConvert.SerializeObject(dataToSend, new KeyValuePairConverter());
var contentVar = new StringContent(jsonData, Encoding.UTF8, "application/json");
try
{
HttpResponseMessage response = await client.PostAsync("/UpdateEvent", contentVar);
var result = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
string contents = await response.Content.ReadAsStringAsync();
var resultJson = JObject.Parse(result);
if ((int)resultJson["status"] == 0)
{
await base.DisplayAlert((string)resultJson["msg"], "", "OK");
return;
}
else if ((int)resultJson["status"] == 1)
{
//I'm currently trying to reload the whole view, before this was calling the method above.
await this.mainPage.Navigation.PushAsync(new NavigationPage(new MasterMenu.MainPage()));
await getRequests();
}
else
{
await base.DisplayAlert("Error procesando la solicitud, intente más tarde", "", "Ok");
return;
}
}
}
catch (Exception ex)
{
Debug.WriteLine("Error update request: {0}", ex);
}
await Task.Delay(1);
}
If I leave it like that, UI will not update. Please help me, as I've been struggling with this issue for 2 days now. It happens exclusively on iOS.
The issue was fixed after updating iOS. The problem was caused because of a buggy iOS version that had problems indexing objects. After updating, everything ran as smoothly as usual. If anyone runs into this issue (exclusively on iOS), try updating both iOS and Xamarin Forms.
I have problem with executing chained payment after obtaining permission from user. I have no troubles to get Access Token and Access Token Secret.
The code should work this way: User (personal type sandbox account) authorizes primary receiver (business type sandbox account) to take money from his account.
Primary receiver sends a part of the sum to the second receiver.
The code is written in ASP.NET MVC but I suppose it has nothing to do with the framework, I'm using PayPalAdaptivePaymentsSDK and PayPalPermissionsSDK
I want to use it in sandbox environment for testing.
I assume it has something to do with application id, I would be very grateful for step-by-step explanation
Here's how I obtain all my credentials:
I login into my developer account.
account1.Username, account1.Password, account1.Signature
- sandbox -> accounts -> I select primary receiver of the payment (business type account) -> API Credentials
applicationId - "APP-80W284485P519543T"
In the config file I specified mode as "sandbox".
I use the same config for executing the payment.
Then I want to execute following code and in payResponse I get errorId 520003 "Authentication failed. API credentials are incorrect."
public class PermissionController : Controller
{
private AdaptivePaymentsService _adaptivePaymentService;
public ActionResult Index()
{
ViewBag.AccessToken = PayPalConfig.AccessToken;
ViewBag.AccessTokenSecret = PayPalConfig.AccessTokenSecret;
return View();
}
public PermissionController()
{
_adaptivePaymentService = new AdaptivePaymentsService(PayPalConfig.GetConfig());
}
public ActionResult GetPermission()
{
RequestPermissionsRequest rp = new RequestPermissionsRequest();
rp.scope = new List<string>();
rp.scope.Add("EXPRESS_CHECKOUT");
Dictionary<string, string> config = PayPalConfig.GetConfig();
rp.callback = "http://localhost:42072/Permission/GetAccessToken";
rp.requestEnvelope = new PayPal.Permissions.Model.RequestEnvelope("en_US");
RequestPermissionsResponse rpr = null;
PermissionsService service = new PermissionsService(config);
rpr = service.RequestPermissions(rp);
string confirmPermissions = "https://www.sandbox.paypal.com/webscr&cmd=_grant-permission&request_token=" + rpr.token;
return Redirect(confirmPermissions);
}
public ActionResult GetAccessToken()
{
Uri uri = Request.Url;
Dictionary<string, string> config = PayPalConfig.GetConfig();
var gat = new GetAccessTokenRequest();
gat.token = HttpUtility.ParseQueryString(uri.Query).Get("request_token");
gat.verifier = HttpUtility.ParseQueryString(uri.Query).Get("verification_code");
gat.requestEnvelope = new PayPal.Permissions.Model.RequestEnvelope("en_US");
GetAccessTokenResponse gats = null;
var service = new PermissionsService(config);
gats = service.GetAccessToken(gat);
_adaptivePaymentService.SetAccessToken(gats.token);
_adaptivePaymentService.SetAccessTokenSecret(gats.tokenSecret);
PayPalConfig.AccessToken = _adaptivePaymentService.getAccessToken();
PayPalConfig.AccessTokenSecret = _adaptivePaymentService.getAccessTokenSecret();
return RedirectToAction("Index");
}
public ActionResult ChainedPayment()
{
ReceiverList receiverList = new ReceiverList();
receiverList.receiver = new List<Receiver>();
Receiver secondaryReceiver = new Receiver(1.00M);
secondaryReceiver.email = "mizerykordia6662-facilitator#gmail.com";
receiverList.receiver.Add(secondaryReceiver);
Receiver primaryReceiver = new Receiver(5.00M);
primaryReceiver.email = "mizTestMerchant#test.com";
primaryReceiver.primary = true;
receiverList.receiver.Add(primaryReceiver);
PayPal.AdaptivePayments.Model.RequestEnvelope requestEnvelope = new PayPal.AdaptivePayments.Model.RequestEnvelope("en_US");
string actionType = "PAY";
string returnUrl = "http://localhost:42072/Home/Index";
string cancelUrl = "https://devtools-paypal.com/guide/ap_chained_payment/dotnet?cancel=true";
string currencyCode = "USD";
_adaptivePaymentService.SetAccessToken(PayPalConfig.AccessToken);
_adaptivePaymentService.SetAccessTokenSecret(PayPalConfig.AccessTokenSecret);
PayRequest payRequest = new PayRequest(requestEnvelope, actionType,
cancelUrl, currencyCode, receiverList, returnUrl);
// it breaks here
PayResponse payResponse = _adaptivePaymentService.Pay(payRequest);
PaymentDetailsRequest paymentDetailsRequest = new PaymentDetailsRequest(new PayPal.AdaptivePayments.Model.RequestEnvelope("en-US"));
paymentDetailsRequest.payKey = payResponse.payKey;
SetPaymentOptionsRequest paymentOptions = new SetPaymentOptionsRequest()
{ payKey = payResponse.payKey };
_adaptivePaymentService.SetPaymentOptions(paymentOptions);
PaymentDetailsResponse paymentDetailsRespons = _adaptivePaymentService.PaymentDetails(paymentDetailsRequest);
ExecutePaymentRequest exec = new ExecutePaymentRequest(new PayPal.AdaptivePayments.Model.RequestEnvelope("en-US"), paymentDetailsRequest.payKey);
ExecutePaymentResponse response = _adaptivePaymentService.ExecutePayment(exec);
return RedirectToAction("Index");
}
}
How to ensure UploadStringCompletedEventHandler event has been executed successfully ? in following code you can see i am calling function UploadMyPOST with my lastreads parameter having some data. Now you can see i am saving a variable named response into the MyClassXYZ varialbe. in the extreme last you can see there is a event which invoked by the method UploadMyPost() is filling the server response into the response variable. Now here issue is UploadMyPost(lastreads) executes successfully but its invoked event does not executes. Even cursor do not go on that event by which i am not able to fill server response into the response variable. So Anyone know any approach by which i can wait until that event successfully execute and i could able to save server response ?
private async void MyMethod(MyClassXYZ lastreads)
{
await UploadMyPOST(lastreads);
MyClassXYZ serverResponse = response;
if (serverResponse.Book == null)
{
//Do Something.
}
}
private void UploadMyPOST(MyClassXYZ lastreads)
{
apiData = new MyClassXYZApi()
{
AccessToken = thisApp.currentUser.AccessToken,
Book = lastreads.Book,
Page = lastreads.Page,
Device = lastreads.Device
};
//jsondata is my global variable of MyClassXYZ class.
jsondata = Newtonsoft.Json.JsonConvert.SerializeObject(apiData);
MyClassXYZ responsedData = new MyClassXYZ();
Uri lastread_url = new Uri(string.Format("{0}lastread", url_rootPath));
WebClient wc = new WebClient();
wc.Headers["Content-Type"] = "application/json;charset=utf-8";
wc.UploadStringCompleted += new UploadStringCompletedEventHandler(MyUploadStringCompleted);
wc.UploadStringAsync(lastread_url, "POST", jsondata);
}
private void MyUploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
{
try
{
if (e.Error == null)
{
string resutls = e.Result;
DataContractJsonSerializer json = new DataContractJsonSerializer(typeof(MyClassXYZ));
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(resutls));
response = (MyClassXYZ)json.ReadObject(ms);
}
else
{
string sx = e.Error.ToString();
}
}
catch(Exception exe)
{
}
}
//After Stephen suggession i used the HttpClient so i have written new code with the help of HttpClient. Code is building successfully but at run time cursor goes out from this method to the parent method where from its calling.
private async Task<string> UploadMyPOST(MyClassXYZ lastreads)
{
string value = "";
try
{
apiData = new LastReadAPI()
{
AccessToken = thisApp.currentUser.AccessToken,
Book = lastreads.Book,
Page = lastreads.Page,
Device = lastreads.Device
};
jsondata = Newtonsoft.Json.JsonConvert.SerializeObject(apiData);
LastRead responsedData = new LastRead();
Uri lastread_url = new Uri(string.Format("{0}lastread", url_rootPath));
HttpClient hc = new HttpClient();
//After following line cursor go back to main Method.
var res = await hc.PostAsync(lastread_url, new StringContent(jsondata));
res.EnsureSuccessStatusCode();
Stream content = await res.Content.ReadAsStreamAsync();
return await Task.Run(() => Newtonsoft.Json.JsonConvert.SerializeObject(content));
value = "kd";
}
catch
{ }
return value;
}
I recommend that you use HttpClient or wrap the UploadStringAsync/UploadStringCompleted pair into a Task-based method. Then you can use await like you want to in MyMethod.
Thank you Stephen Clear you leaded me in a right direction and i did POST my request successfully using HttpClient.
HttpClient hc = new HttpClient();
hc.BaseAddress = new Uri(annotation_url.ToString());
HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Post, myUrl);
HttpContent myContent = req.Content = new StringContent(myJsonData, Encoding.UTF8, "application/json");
var response = await hc.PostAsync(myUrl, myContent);
//Following line for pull out the value of content key value which has the actual resposne.
string resutlContetnt = response.Content.ReadAsStringAsync().Result;
DataContractJsonSerializer deserializer_Json = new DataContractJsonSerializer(typeof(MyWrapperClass));
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(resutlContetnt.ToString()));
AnnotateResponse = deserializer_Json.ReadObject(ms) as Annotation;