HttpClient SendAsync no error or data returned - dotnet-httpclient

var client = new HttpClient();
HttpRequestMessage httpRequestMessage = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://api.stubhubsandbox.com/login"),
};
httpRequestMessage.Headers.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("text/html"));
httpRequestMessage.Headers.Add("Host", "api.stubhubsandbox.com");
httpRequestMessage.Content = new StringContent(finalParameters);
httpRequestMessage.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(ContentType);
httpRequestMessage.Content.Headers.ContentLength = 80;
httpRequestMessage.Headers.Add("Authorization", Authorization);
Console.WriteLine(httpRequestMessage.ToString());
var response = client.SendAsync(httpRequestMessage).ContinueWith(respTask =>
{
Console.WriteLine("Response: {0}", respTask.Result);
});
Console.ReadLine();
I have my fiddler open and I did not see my request has been sent. It did not return or throw any exceptions?
It looks somehow I can not invoke my call over https?

Related

IdentityServer4 and external oauth privider: The oauth state was missing or invalid

I'm trying to implement external oauth authentication within IdentityServer4.
All auth requests goes successfully. I have a message AuthenticationScheme: Identity.External signed in. in app log.
But when authentication process tries to go back to ExternalLoginCallback action it falls with Error 500 (The oauth state was missing or invalid) after HTTP 302.
Screenshot is here
Result 302. Request https://localhost:5999/Account/ExternalLoginCallback?state=xxx&code=xxx&session_state=xxx
Then request goes to https://localhost:5999/Account/ExternalLoginCallback (without any parametres)
My IS4 Startup
IdentityServerConfiguration.AddIdentityServer(services, _configuration);
services
.AddAuthentication()
.AddTinkoff(_configuration)
.AddSber(_configuration)
.AddEsia(_configuration);
AddTinkoff extension method:
public static AuthenticationBuilder AddTinkoff(this AuthenticationBuilder builder, IConfiguration config)
{
return builder.AddOAuth("TinkoffId", "Tinkoff ID", options =>
{
options.AuthorizationEndpoint = "https://id.tinkoff.ru/auth/authorize?response_type=code";
options.TokenEndpoint = "https://id.tinkoff.ru/auth/token?grant_type=authorization_code";
options.UserInformationEndpoint = "https://id.tinkoff.ru/userinfo/userinfo";
options.CallbackPath = "/Account/ExternalLoginCallback";
options.ClientId = "xxx";
options.ClientSecret = "xxxx";
options.SaveTokens = true;
options.SignInScheme = IdentityConstants.ExternalScheme;
options.BackchannelHttpHandler = new TinkoffAuthorizingHandler(new HttpClientHandler(), options);
options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "name");
options.ClaimActions.MapJsonKey(ClaimTypes.Email, "email", ClaimValueTypes.Email);
options.ClaimActions.MapAll();
options.Events = new OAuthEvents
{
OnCreatingTicket = async context =>
{
var request = new HttpRequestMessage(HttpMethod.Post, context.Options.UserInformationEndpoint);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);
request.Headers.Add(
HttpRequestHeader.ContentType.ToString(),
"application/x-www-form-urlencoded"
);
request.Content = new FormUrlEncodedContent(new List<KeyValuePair<string, string>>() {
new KeyValuePair<string, string>("client_id",options.ClientId),
new KeyValuePair<string, string>("client_secret",options.ClientSecret)
});
var response = await context.Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, context.HttpContext.RequestAborted);
response.EnsureSuccessStatusCode();
var user = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
context.RunClaimActions(user.RootElement);
},
//OnTicketReceived = async context =>
//{
// context.HttpContext.User = context.Principal;
// //context.SkipHandler();
//}
};
//options.Scope.Add("profile");
//options.Scope.Add("email");
//options.Scope.Add("phone");
});
}
My ExternalLogin action:
[HttpPost]
[HttpGet]
[AllowAnonymous]
public IActionResult ExternalLogin(string provider, string returnUrl = null)
{
_logger.LogInformation($"External login fired. ReturnUrl='{returnUrl}'. Provider='{provider}'");
var redirectUrl = Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl });
var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
return Challenge(properties, provider);
}
ExternalLoginCallback action not fired while debug.
What I'm doing wrong. Why request redirects to itself without params?
Thank you.
I solved an issue for me.
I added
OnTicketReceived = async context =>
{
context.HttpContext.User = context.Principal;
//context.SkipHandler();
context.ReturnUri += $"/{context.Request.QueryString}";
}
Now it works as expected

Why do I get an Unsupported Media Type on this request?

I am making the below request from a WPF app to an MVC Core app that acts as an API:
var formContent = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("userName", userName),
new KeyValuePair<string, string>("password", password)
});
////var content = new StringContent($"{{\"username\": {userName}, \"password\": {password}}}", Encoding.UTF8, "application/json");
var resp = await _client.PostAsync("api/Token", formContent);
var json = await resp.Content.ReadAsStringAsync();
var tw = JsonConvert.DeserializeObject<TokenWrapper>(json);
return tw.Token;
When I inspect resp with a breakpoint, after the PostAsync call, I see a 415 - Unsupported Media Type error. A breakpoint on the first line of the action isn't event hit, so I think the request isn't even reaching the controller.
The controller action looks like this:
public async Task<string> LoginAsync(string userName, string password)
{
var formContent = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("userName", userName),
new KeyValuePair<string, string>("password", password)
});
////var content = new StringContent($"{{\"username\": {userName}, \"password\": {password}}}", Encoding.UTF8, "application/json");
var resp = await _client.PostAsync("api/Token", formContent);
var tempContent = await resp.Content.ReadAsStringAsync();
var json = await resp.Content.ReadAsStringAsync();
var tw = JsonConvert.DeserializeObject<TokenWrapper>(json);
return tw.Token;
}
I would expect FormUrlEncodedContent to imply the content type and work, as in the high number of examples I have seen like this. Why am I getting this 415 error?
Try by setting the Media Typeas below:
var content = new StringContent(formContent.ToString(), Encoding.UTF8, "application/json");
var result = await _client.PostAsync("http://example.com/api/Token", content);
Also PostAsync accepts parameters of requestUri and content , your code is the missing Absolute requestUri.

Returning json result while consuming web api from mvc controller

I am consuming an external web api through mvc controller with HttpClient. My web api do return json-formatted content.
How do i return the same json-formatted content of web api response in my mvc controller while consuming the web api? I am expecting something like this.
public async JsonResult GetUserMenu()
{
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri(url);
HttpResponseMessage response = await client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsJsonAsync();
}
}
}
Using Json.Net you could do something like this:
public async Task<JsonResult> GetUserMenu()
{
string result = string.Empty;
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri(url);
HttpResponseMessage response = await client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
result = await response.Content.ReadAsStringAsync();
}
}
return Json(Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(result));
}
Here below an example of inserting log for action.
[HttpPost]
public async System.Threading.Tasks.Task<ActionResult> ChangePassword(ChangePasswordInfo model)
{
var omodelPwd = loginContext.UsersChangePasswordRequest(objAuthModel.oUsers.iID);
TempData[LKTransferDashboardCommon.Notification] = JsonConvert.SerializeObject(new Response { Success = false, ResponseString = "Invalid Old Password!" });
var auditLog = LKTransferDashboardCommon.PrepareAuditLogData(
"ChangePassword-Fail",
objAuthModel.oUsers.iID,
nameof(ChangePassword),
Request.ServerVariables["REMOTE_ADDR"],
"AdministrationController",
objAuthModel.oUsers.Name
);
await AuditLogHelper.ExecuteAsync(auditLog, null, null, null, null, null).ConfigureAwait(false);
return View(model);
}

JIRA REST API how to add attachment using c#

I am using jira api to add attachment to the issue
According to documentation i have set few things.
submit a header of X-Atlassian-Token: nocheck with the request.
The name of the multipart/form-data parameter that contains attachments must be "file".
resource expects a multipart post.
& when i run my code i get internal server error.
my code is as follows
string postUrl = "http://localhost:8080/rest/api/latest/issue/TES-99/attachments";
System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
client.DefaultRequestHeaders.Add("X-Atlassian-Token", "nocheck");
client.BaseAddress = new System.Uri(postUrl);
byte[] cred = UTF8Encoding.UTF8.GetBytes(credentials);
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(cred));
var content = new MultipartFormDataContent();
var values = new[]
{
new KeyValuePair<string, string>("file", "e:\\z.txt")
};
foreach (var keyValuePair in values)
{
content.Add(new StringContent(keyValuePair.Value), keyValuePair.Key);
}
var result = client.PostAsync(postUrl, content).Result;
please suggest where i am making mistake
I solved this too. now i am able to add attachment using JIRA API with C#.
i was making mistake with this piece of code.
var values = new[]
{
new KeyValuePair<string, string>("file", "e:\\z.txt")
};
foreach (var keyValuePair in values)
{
content.Add(new StringContent(keyValuePair.Value), keyValuePair.Key);
}
this is my code.
string postUrl = "http://localhost:8080/rest/api/latest/issue/" + projKey + "/attachments";
System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
client.DefaultRequestHeaders.Add("X-Atlassian-Token", "nocheck");
client.BaseAddress = new System.Uri(postUrl);
byte[] cred = UTF8Encoding.UTF8.GetBytes(credentials);
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(cred));
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
MultipartFormDataContent content = new MultipartFormDataContent();
**//The code which solved the problem**
HttpContent fileContent = new ByteArrayContent(File.ReadAllBytes(filePath));
fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse(mimeType);
content.Add(fileContent, "file",fileName);
var result = client.PostAsync(postUrl, content).Result;
This is my working code.
[HttpPost]
public async Task<IActionResult> CreateTicketWithAttachent(IFormFile file, [FromQuery] string issuekey)
{
try
{
string url = $"http://jiraurl/rest/api/2/issue/{issuekey}/attachments";
var client = new HttpClient();
var header = new AuthenticationHeaderValue("Basic", "your-auth-key");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Authorization = header;
client.DefaultRequestHeaders.Add("X-Atlassian-Token", "no-check");
MultipartFormDataContent multiPartContent = new MultipartFormDataContent("-data-");
ByteArrayContent byteArrayContent;
using (var ms = new MemoryStream())
{
file.CopyTo(ms);
var fileBytes = ms.ToArray();
//string fileString = Convert.ToBase64String(fileBytes);
byteArrayContent = new ByteArrayContent(fileBytes);
}
multiPartContent.Add(byteArrayContent, "file", file.FileName);
var response = await client.PostAsync(url, multiPartContent);
var result = response.Content.ReadAsStringAsync().Result;
if (response.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception(result);
return Ok();
}
catch (Exception e)
{
return BadRequest(e);
}
}

How do I POST a httpclient to a WEB API? (simple as possible way for my highscore table)

My windows phone client sends a piece of JSON that represents the Name and Score... Should I be using the Class from the Web API instead ? What is the code to send the object to the server rather than the raw json?
private void btnCreateSampleScore_Click(object sender, RoutedEventArgs e)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://punkoutersoftware.azurewebsites.net");
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("Bob", "2.65")
});
var result = client.PostAsync("/api/DrunkMeterScore", content).Result;
string resultContent = result.Content.ReadAsStringAsync().Result;
Console.WriteLine(resultContent);
//DrunkMeterScore dms = new DrunkMeterScore();
//dms.Name = "Bob";
//dms.Score = 2.42;
}
}
The server is using the plain Web API template
// POST api/DrunkMeterScore
public HttpResponseMessage PostDrunkMeterScore(DrunkMeterScore drunkmeterscore)
{
if (ModelState.IsValid)
{
db.DrunkMeterScores.Add(drunkmeterscore);
db.SaveChanges();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, drunkmeterscore);
response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = drunkmeterscore.DrunkMeterScoreId }));
return response;
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
}
edit1:
I tried both of these.. They both hang and never come back during the PostAsync calls :(
var client = new HttpClient();
client.BaseAddress = new Uri("http://punkoutersoftware.azurewebsites.net");
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
var score = new DrunkMeterScore() { Name = "Joe", Score = 2.67 };
//MediaTypeFormatter jsonFormatter = new JsonMediaTypeFormatter();
//HttpContent content = new ObjectContent<DrunkMeterScore>(score, jsonFormatter);
//var resp = client.PostAsync("api/DrunkMeterScore", content).Result;
//Uri scoreUri = null;
//HttpResponseMessage response = client.PostAsJsonAsync("api/DrunkMeterScore", score).Result;
//if (response.IsSuccessStatusCode)
//{
// scoreUri = response.Headers.Location;
//}
//else
//{
// Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
//}
To serialize objects you need the ObjectContent class which for the wp8 is only available as an alpha release.
Use the package console to do,
Install-Package Microsoft.AspNet.WebApi.Client -Pre
Should be something like this. I did this from memory so YMMV.
DrunkMeterScore dms = new DrunkMeterScore();
dms.Name = "Bob";
dms.Score = 2.42;
var content = new ObjectContent(dms, new JsonMediaTypeFormatter());
var result = client.PostAsync("/api/DrunkMeterScore", content).Result;

Resources