I have a web api and a web app both written in asp.net and want to send a PDF from the api to the web app for display in a new browser window, the api is working sending the file as a streamcontent but i cannot find a way of prompting the client browser to display this in a new window, i cant make the browser make the request to the api directly as i need to add an authentication header first.
Does anyone have any ideas?
As an alternative if this is not possible i could also have the file downloaded to the client machine but i also dont know how to do that.
api code:
public HttpResponseMessage Get()
{
var response = new HttpResponseMessage();
string auth;
try
{
auth = Request.Headers.Authorization.Parameter;
}catch { return new HttpResponseMessage(HttpStatusCode.Unauthorized); }
if (auth == "test" || auth == null)
{
FileStream stream = File.OpenRead(Path.Combine(Storage.FilesDirectory, "0d23b37f-3ade-4342-beea-c6ba2cbf83cb.file"));
response.Content = new StreamContent(stream);
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/pdf");
return response;
}
else return new HttpResponseMessage(HttpStatusCode.Forbidden);
}
Current client code that gets the stream but i dont know how to display that in the browser:
HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Get, API.DocumentUrl);
req.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", "test");
var res = await HttpClientSingleton.Client.SendAsync(req);
Related
Hi so we have an external web api we want to call to get data out. It is using oauth 2.0. Can somebody please explain how we would go about doing this in .NET either vb.net or c#. I have in the past created api, however this one seems very complicated. Firstly you have to be signed into their oauth web page they have which generates some cookies, using these cookies by syncing them up in postman we can see the data, however we need this to be within our .net app. Can somebody please help how we go about this. Some code would be useful.
Thanks
This is how usually OAuth 2 authentication works.
You basically log in with username and password (optional second factor) and then you receive a token, the so called Json Web Token or JWT (it holds encrypted information about your user, your access roles or groups you are member of as well as some timestamp which is the expiration time of the token).
In every subsequent request you make to the server, you pass this token in the request header (or in your case as cookie).
Example code:
Login request:
HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Post, new Uri(_baseUrl, "token"));
string body = JsonConvert.SerializeObject(new
{
Username = _userName,
Password = _password,
secondFactor = secondFactor
});
httpRequest.Content = new StringContent(body, Encoding.UTF8, "application/json");
var response = await client.SendAsync(httpRequest);
var responseContent = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
TokenResult r = JsonConvert.DeserializeObject<TokenResult>(responseContent);
if (!string.IsNullOrWhiteSpace(r.token))
{
_token = r.token;
_tokenValidity = r.expirationDate;
_refreshToken = r.refreshToken;
_refreshTokenValidity = r.refreshTokenExpirationDate;
return _token;
}
else
{
throw new Exception($"Failed to get token from server.\r\n{responseContent}");
}
}
Now you use the _token in subsequent requests in the request header:
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _token);
using HttpResponseMessage response = await client.GetAsync(new Uri(_baseUrl, relativePath));
if (response.IsSuccessStatusCode)
{
using var stream = await response.Content.ReadAsStreamAsync();
stream.Position = 0;
using var reader = new StreamReader(stream);
reader.ReadToEnd();
}
Please note, that usually the token has a certain lifetime after which it is basically useless. Some APIs offer a refresh token with which a new token can be requested without the user having to log in again with username and password, but that's beyond the scope of this question.
You said you have to use the token as cookie? Well there are APIs which work like this but personally I've never seen one like this, which is why I can't you help very much, but it shouldn't be much more than putting the token you got into a cookie with a certain name.
Hope this helps.
Not sure what you are asking. I have a controller code where I use web api call to authenticate user. You can use your own model to pass the data. If your web api expects token for request, then you might have to get the token first to give a call to any method. Hope this helps.
OktaUserDetailsModel Model = new OktaUserDetailsModel();
Model.username = model.UserName;
Model.password = model.Password;
using (var httpClient = new HttpClient())
{
HttpContent inputContent = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(Model), System.Text.Encoding.UTF8, "application/json");
HttpResponseMessage response = httpClient.PostAsync(ConfigurationManager.AppSettings["OktaAPIuri"], inputContent).Result;
if (response.IsSuccessStatusCode)
{
string strResponse = (new JavaScriptSerializer()).Deserialize<string>(response.Content.ReadAsStringAsync().Result);
if (strResponse.ToUpper() == "TRUE")
return OktaSingleSignOnLogin(astrReturnUrl, model.UserName);
else
return ErrorPage();
}
else
{
return ErrorPage();
}
}
I have a web page(.../ui/mydashboard.aspx ) which I want to display on my xamarin forms app, the problem is the web page doesn't use query parameters to provide for the users authentication details is it possible to access the web page(.../ui/mydashboard.aspx ) without having to go through the login page in my mobile app?
public Dashboard ()
{
InitializeComponent ();
webView.Source = "http://dev.webapp.com/ui/mydashboard.aspx";
}
You can send the data as the body of post request .If you don't want to let user input it , you can set a default value .
HttpClient client = new HttpClient() { Timeout = TimeSpan.FromSeconds(30) };
// set the params here
HttpContent content = new StringContent(JsonConvert.SerializeObject(objectToPost), Encoding.UTF8, "application/x-www-form-urlencoded");
var response = await client.PostAsync(new Uri("http://your.url"), content);
if (response.IsSuccessStatusCode) {
var responseFromServer = await response.Content.ReadAsStringAsync();
}
else {
// handle errors
}
I have created a web service using .NET Web API. The web service part works great, I am able to send the zip file using Advanced REST Client. The problem is that I can't send the zip file programmatically. Here is the Advanced REST Client Request Headers:
I have try some things but without success. I am not posting what I have try, considering that this is basic stuff for web developers (I am desktop developer), but if it is necessary, I will. Thank you in advance.
EDIT: This is my recent version
private async void BeginUpdate(bool webserverStatus)
{
if (!webserverStatus) return;
var httpClient = new HttpClient();
var form = new MultipartFormDataContent();
var byteArray = File.ReadAllBytes("myUpdatePackage.zip");
form.Add(new ByteArrayContent(byteArray, 0, byteArray.Length), "myUpdatePackage", "myUpdatePackage.zip");
HttpResponseMessage response = await httpClient.PostAsync(#"http://localhost:9000/api/file/", form);
response.EnsureSuccessStatusCode();
httpClient.Dispose();
string sd = response.Content.ReadAsStringAsync().Result;
}
I realized that on Advanced REST Client, I was it using PUT, meanwhile on my C# application I call it using POST
HttpResponseMessage response = await httpClient.PostAsync(#"http://localhost:9000/api/file/", form);
So, here is the complete code:
private async void BeginUpdate(bool webserverStatus)
{
if (!webserverStatus) return;
var byteArray = File.ReadAllBytes("myUpdatePackage.zip");
var httpClient = new HttpClient();
var form = new MultipartFormDataContent();
form.Add(new ByteArrayContent(byteArray, 0, byteArray.Length), "myUpdatePackage", "myUpdatePackage.zip");
HttpResponseMessage response = await httpClient.PutAsync(#"http://localhost:9000/api/file/", form);
response.EnsureSuccessStatusCode();
httpClient.Dispose();
string sd = response.Content.ReadAsStringAsync().Result;
}
More details on this question
When creating an anonymous sharing link for a notebook section group using the OneNote API, the shared link opens the OneDrive directory listing instead of opening the OneNote web page for the shared section group.
The URL returned from the call to GetOrCreateAnonymousSharingLink looks like this:
https://company-my.sharepoint.com/:o:/g/personal/aaa_company_onmicrosoft_com/Eas72kadUjRBs9_EmWWWVncBaNLxzujnkFlGRobX6IOBHw
The directory listing displayed has a .one link and a .onetoc2 link. Clicking either link will open the OneNote site and display the section and its pages.
Shared links that are manually created are in the same format as above, however, they contain a query parameter e.g. e=1zreF2
Should this parameter be included in the URL returned by GetOrCreateAnonymousSharingLink? Or, have I done something to my Notebooks that might be causing the directory listing to display instead of the actual notebook.
Here's the code:
internal static async Task<string> GenerateSharingLink(string sectionGroupId, SDKHelper.NotebookSecurityRole securityRole) {
string result;
string accessLevel = "{\"accessLevel\":\"Edit\"}";
var accessToken = await SDKHelper.GetAccessToken(SDKHelper.ApiResourceType.OneNoteApi);
string requestUri = $"https://www.onenote.com/api/v1.0/users/aaa#company.onmicrosoft.com/notes/sectiongroups/{sectionGroupId}/Microsoft.OneNote.Api.GetOrCreateAnonymousSharingLink";
var accessLevelJson = new StringContent(JsonConvert.SerializeObject(accessLevel), Encoding.UTF8, "application/json");
using(var client = new HttpClient()) {
client.BaseAddress = new Uri("https://onenote.com");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
client.DefaultRequestHeaders
.Accept
.Add(new MediaTypeWithQualityHeaderValue("application/json"));
using(var request = new HttpRequestMessage(HttpMethod.Post, requestUri)) {
request.Content = new StringContent(accessLevel, Encoding.UTF8, "application/json");
using(var response = await client.SendAsync(request)) {
if (!response.IsSuccessStatusCode) {
throw new Microsoft.Graph.ServiceException(
new Error {
Code = response.StatusCode.ToString(),
Message = await response.Content.ReadAsStringAsync()
});
}
result = await response.Content.ReadAsStringAsync();
}
}
}
return result;
}
I am creating a Metro App that makes a HTTP Post request to a webserver to obtain JSON data. Initially I use the same code to logon to the web server and the HTTP Post request returns fine. It is only later that I run into an issue where the code hangs when I call the SendAsync() method.
I used wireshark to view the network traffic and I did see the server returning a response. So I am not sure why the call is not completing. Anyone have any ideas?
Here is the code I am using:
var httpHandler = new HttpClientHandler();
httpHandler.CookieContainer = __CookieJar;
var httpClient = new HttpClient(httpHandler);
UserAgentDetails userAgent = UserAgentDetails.GetInstance();
httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(userAgent.UserAgentString);
foreach (string key in __colHeaders)
httpClient.DefaultRequestHeaders.Add(key, __colHeaders[key]);
var content = new StringContent(postData);
if (contentType != null && contentType.Length > 0)
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
var requestMsg = new HttpRequestMessage(HttpMethod.Post, new Uri(url));
requestMsg.Content = content;
requestMsg.Headers.TransferEncodingChunked = true;
var responseMsg = await httpClient.SendAsync(requestMsg);
// no return from method after logon