Microsoft Graph Content return null - c#

I am trying to retrieve the content of my word document stored in my company SharePoint.
The code is as follows:
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
DriveItem document = await graphClient.Sites[_siteId].Drive.Items[remoteId].Request().GetAsync();
DocumentDTO dto = new DocumentDTO { Content = document.Content };
The dto has accessed the other information contained in the DriveItem such as Id and Name, but I don't understand why I can't access the content.
Looking for any possible help :-) Thanks

If you look at the example response in the docs, the content is not returned when you make call as you have done in your example.
To get the content you would need to make a different/separate request as shown here.
Therefore, your code should look like something like this to get the content.
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
Stream content = await graphClient.Sites[_siteId].Drive.Items[remoteId].Content.Request().GetAsync();
DocumentDTO dto = new DocumentDTO { Content = content };

I end up doing this to retrieve my content in Stream.
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
var document = await graphClient.Sites[_siteId].Drive.Items[remoteId].Request().GetAsync();
var url = document.AdditionalData["#microsoft.graph.downloadUrl"].ToString();
HttpClient http = new HttpClient();
var response = await http.GetAsync(url);
var content = await response.Content.ReadAsStreamAsync();

Related

.NET Azure SDK - get raw response for async pageable result

I'm using the lastest Azure.ResourceManager SDK for .NET to list all resources in a subscription, this works fine:
var armClient = new ArmClient(new DefaultAzureCredential());
var subscription = await armClient.GetDefaultSubscriptionAsync();
await foreach(var resource in subscription.GetGenericResourcesAsync())
{
_logger.LogInformation("Got resource {id}", resource.Id);
}
However, I would like to get access to the raw HTTP response. This article explains how to do this for other, non-pageable responses. So I'm looking for a way to do this in my case, too. Something like GetRawResponse() - but I don't have a response object.
Please try something like the following:
var credential = new DefaultAzureCredential();
var armClient = new ArmClient(credential);
var subscription = await armClient.GetDefaultSubscriptionAsync();
var allResources = subscription.GetGenericResourcesAsync();
await foreach(Page<GenericResource> page in allResources.AsPages())
{
Response http = page.GetRawResponse();
Stream contentStream = http.ContentStream;
// Rewind the stream
contentStream.Position = 0;
using (StreamReader reader = new StreamReader(contentStream))
{
Console.WriteLine(reader.ReadToEnd());
}
}
For more details, please see this link: https://learn.microsoft.com/en-us/dotnet/azure/sdk/pagination

How can I create HttpRequest (in C#) with attached files?

As title says, can find plenty of resources on posting to an endpoint (from JS, for example), but how do I construct a HttpRequest (in C# .Net core) with files?
What I've Tried
var myRequest = new DefaultHttpContext().Request;
myRequest.Form.Files // GET only!
I can't seem to set the Files collection (IFormFileCollection), I can only get it.
Further Context
This is to integration test an endpoint. Except I have to hit the method, not reach it via URL (for one reason or another). The method accepts a HttpRequest and parses out the Form.Files collection. Hence I need to add some files for my assertions.
Did you already try something like this:
using (var stream = new MemoryStream(fileBytes))
{
var bla = new DefaultHttpContext().Request;
bla.Form.Files.Append(new Microsoft.AspNetCore.Http.Internal.FormFile(stream, 0, stream.Length, "file.txt", "file.txt"));
}
you can achieve this by take advantage of the following Method
public async Task<string> UploadFile(string filePath)
{
if (string.IsNullOrWhiteSpace(filePath))
{
throw new ArgumentNullException(nameof(filePath));
}
if (!File.Exists(filePath))
{
throw new FileNotFoundException($"File [{filePath}] not found.");
}
using var form = new MultipartFormDataContent();
using var fileContent = new ByteArrayContent(await File.ReadAllBytesAsync(filePath));
fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
form.Add(fileContent, "file", Path.GetFileName(filePath));
form.Add(new StringContent("789"), "userId");
form.Add(new StringContent("some comments"), "comment");
form.Add(new StringContent("true"), "isPrimary");
var response = await _httpClient.PostAsync($"{_url}/api/files", form);
response.EnsureSuccessStatusCode();
var responseContent = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<FileUploadResult>(responseContent);
return result.Guid;
}
this method was snipped from a good blog: https://codeburst.io/upload-download-files-using-httpclient-in-c-f29051dea40c
It would look something like this:
var context = new DefaultHttpContext();
var formFiles = new FormFileCollection();
var formValues = new Dictionary<string, StringValues>() { };
var formCollection = new FormCollection(formValues, formFiles);
context.Features.Set<IFormFeature>(new FormFeature(formCollection));
Fill in the formFiles and formValues variables based on what you're trying to test. The key here is setting the feature to your custom FormFeature. That will cleanly plug into the default behavior of .Form and ReadFormAsync
PS: This is for unit testing assuming you're not trying to send a real file to the server side, otherwise mustafa hassan's answer works

C# Get Request Directus

recently i discovered this amazing cms called Directus, where you can manage your database and Tables with web request and Json.
Everything worked fine creating,updating,reading...till i came to the point where i want to Create (Upload) a Image using WebRequest.
Im basicly reading a image as Base64 and writing the data along with the parameters in the Uri using a simple GET request exactly like described in API.
Regardless what i try and use the Images Never show up in my Files.
Am i doing something wrong or forgetting something?
Or does directus want something else from me?
My first try:
public static async void UploadUserImage() {
var uri = "http://IP/Directus/api/1/files?access_token=SecretApiKey";
var data = GetImageData();
var finalUri = $"{uri}&data={data}";
using (var client = new HttpClient()) {
var responseString = await client.GetStringAsync(finalUri);
Console.Write(responseString);
}
}
My Second try with Json:
public static async void UploadUserImage() {
var uri = "http://IP/Directus/api/1/files?access_token=SecretApiKey";
var data = GetImageData();
var finalUri = $"{uri}&data={data}";
var postModel = new PictureModel {
data = data,
title = "Test",
name = "test"
};
using (var client = new HttpClient())
{
// Serialize our concrete class into a JSON String
var content = JsonConvert.SerializeObject(postModel);
var contenta = new StringContent(content, Encoding.UTF8, "application/json");
var response = await client.PostAsync(finalUri, contenta);
var result = await response.Content.ReadAsByteArrayAsync();
Console.Write(System.Text.Encoding.UTF8.GetString(result));
}
}
The docs is incorrect it's actually a POST request. Thanks for pointing that out.
To upload a new file you need three provide three values:
{
"name": "image.png",
"type": "image/png",
"data": "base64content"
}
The data content has to be in this format data:<mime-type>;base64,<data-content> so it will look something like this: data:image/png;base64,ThisIsABase64Content
We are updating the docs and removing the data:image/png which is unnecessary.

Uploading a document from Windows Store App to a SharePoint 2013 document library

I need to upload a document to a SharePoint 2013 document library (can be via Rest Api/other) using C# & also retrieve the unique id/location of the document currently uploaded. Please suggest to me a recommended way. Any help would be appreciated.
Here is an example of uploading a file and using the server response to get the ID of the document which can be used to get the location though the response may also contain the URL of the document if you poke through the JSON.
FileOpenPicker picker = new FileOpenPicker();
picker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
picker.ViewMode = PickerViewMode.Thumbnail;
// Filter to include a sample subset of file types.
picker.FileTypeFilter.Clear();
picker.FileTypeFilter.Add(".bmp");
picker.FileTypeFilter.Add(".png");
picker.FileTypeFilter.Add(".jpeg");
picker.FileTypeFilter.Add(".jpg");
// Open the file picker.
StorageFile path = await picker.PickSingleFileAsync();
if (path != null)
{
string url = "https://YourSite.com/Subsite/";
HttpClient client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true });
client.BaseAddress = new System.Uri(url);
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("Accept", "application/json;odata=verbose");
client.DefaultRequestHeaders.Add("X-RequestDigest", digest);
client.DefaultRequestHeaders.Add("X-HTTP-Method", "POST");
client.DefaultRequestHeaders.Add("binaryStringRequestBody", "true");
IRandomAccessStream fileStream = await path.OpenAsync(FileAccessMode.Read);
var reader = new DataReader(fileStream.GetInputStreamAt(0));
await reader.LoadAsync((uint)fileStream.Size);
Byte[] content = new byte[fileStream.Size];
reader.ReadBytes(content);
ByteArrayContent file = new ByteArrayContent(content);
HttpResponseMessage response = await client.PostAsync("_api/web/lists/getByTitle(#TargetLibrary)/RootFolder/Files/add(url=#TargetFileName,overwrite='true')?#TargetLibrary='Project Photos'&#TargetFileName='TestUpload.jpg'", file);
response.EnsureSuccessStatusCode();
if (response.IsSuccessStatusCode)
{
//Get file ID from SharePoint
var info = response.Content.ReadAsStringAsync();
JsonObject d = JsonValue.Parse(info.Result).GetObject();
string id = d["d"].GetObject()["ListItemAllFields"].GetObject().GetNamedValue("ID").Stringify();
}
}
'digest' is a string you have to retrieve from SharePoint to authenticate any further REST calls. You can find an example of how to do that and any other common task for a Store App for SharePoint here:
https://arcandotnet.wordpress.com/2015/04/01/sharepoint-2013-rest-services-using-c-and-the-httpclient-for-windows-store-apps/

How to retrieve HttpResponseMessage content headers for a live media stream (in a windows store app using c#)

I am making an online radio radio app for Windows 8.1 and wanted to communicate with shoutcast servers using the new Windows.Web.Http API (in order to send custom HTTP headers to get metadata from the live media stream).
The response headers are empty, and I need to read the content headers before starting to read the stream data.
This is the code I tried to use:
Uri uri = new Uri(Url);
var baseFilter = new HttpBaseProtocolFilter();
ShoutcastHttpFilter filter = new ShoutcastHttpFilter(baseFilter);
var HClient = new HttpClient(filter);
HttpResponseMessage response = await HClient.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead);
Task streaming = null;
Stream stream = null;
stream = response.Content.ReadAsInputStreamAsync().GetResults().AsStreamForRead();
string str = response.Content.Headers["Icy-MetaInt"];
When I run/debug the code, the content appears as "unbuffered" and has no headers.
How can I get the content headers and the stream?
This the code I used in ShoutcastHttpFilter:
request.Headers.Clear();
request.Headers.Add("Icy-MetaData", "1");
request.Headers["User-Agent"] = "VLC media player";
request.Headers["Connection"] = "Close";
HttpResponseMessage response = await innerFilter.SendRequestAsync(request).AsTask(cancellationToken, progress);
cancellationToken.ThrowIfCancellationRequested();
return response;
If the header name does not start with Content-*, then the header must be in the response headers.
Do this:
Uri uri = new Uri("http://example.com");
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.GetAsync(
uri,
HttpCompletionOption.ResponseHeadersRead);
string value = response.Headers["Icy-MetaInt"];

Categories