Android Xamarin.Auth 1.2.2 How to Update Uploaded Cloud Storage File LastModifiedDate? - xamarin

With Xamarin.Forms, I am using OneDrive SDK on UWP to access OneDrive and it is working good. I am uploading/downloading small data files and I use the following code to change a file's LastModifiedDate:
Item itemUpdate1 = new Item();
itemUpdate1.FileSystemInfo = new Microsoft.OneDrive.Sdk.FileSystemInfo {LastModifiedDateTime = lastModifiedDateTime };
await oneDriveClient1.Drive.Items[item1.Id].Request().UpdateAsync(itemUpdate1);
On Android, I use Xamarin.Auth to access OneDrive and I cannot figure out how to update a file's LastModifiedDate. I am using the following code to sign in and upload the file:
var auth = new OAuth2Authenticator(clientId: clientId, scope: storageScopes1, authorizeUrl: new System.Uri("https://login.live.com/oauth20_authorize.srf"),
redirectUrl: new System.Uri("https://login.live.com/oauth20_desktop.srf"));
System.Uri dataFileUri = new System.Uri("https://api.onedrive.com/v1.0/drive/special/approot:/" + dataFileName1 + ":/content");
var requestUpload = new OAuth2Request("PUT", dataFileUri, null, account);
I would like to know if OAuth2Request can be used to update the file's LastModifiedDate or if there is another way to do it?
Thanks for your help.

Short answer is no. Xamarin.Auth is only to handle the Authentication between your App and the OneDrive Rest Api.
If you want to modify any of the properties of a file in OneDrive you will need to either use a OneDrive SDK for Android as you do in the UWP project or do these modification using the Rest API directly as you did to upload the file.
UPDATE 1
System.Uri dataFileUri = new System.Uri("https://api.onedrive.com/v1.0/drive/special/approot:/" + dataFileName1 + ":/content");
var requestUpload = new OAuth2Request("PUT", dataFileUri, null, account);
As you did in the code above, if you can get the endpoint for the OneDrive REST API to modify the file's properties (like LastModifiedDate) you could be able do it with OAuth2Request.
Go to the OneDrive Dev Portal and try to get that information from the documentation.

Related

How to save a csv or txt in Xamarin UWP app?

Today I've got a question about saving a .csv or .txt file within a Xamarin app on UWP platform. I am trying to save a file I create in my code call tags.csv. My goal is to have no .csv's saved initially, I create an instance in my code, then save it and create a new .csv file when my code executes. The creation and filling of the .csv occurs in one function which triggers based on a Button instance in my app. Also, ideally I could make it save in a location determined by a file explorer popup.
I have tried two routes so far to make and save a .csv file, the CSVExport package and CSVhelper package. Both I have been able to download and add to my project from NuGet successfully.
I have tried separately a simple implementation of each, basically just taking their Example code to see if it would work in my UWP app. Here is the respective code
// CSVExport methods, two ways to save
var myExport = new CsvExport();
...
File(myExport.ExportToBytes(), "text/csv", "results.csv"); // method 1
myExport.ExportToFile("./results.csv"); // method 2
// CSVhelper method
var records = new List<Foo>
{
new Foo { Id = 1, Name = "one" },
};
using (var writer = new StreamWriter("./tags.csv"))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csv.WriteRecords(records);
}
Here is the error I am receiving: System.UnauthorizedAccessException: 'Access to the path C:...(filepath)...BLE.Client.UWP\bin\x86\Debug\AppX\tags.csv' is denied.'
Whenever the code reaches my saving of the .csv file, it crashes the app and Visual Studio 2022 gives me this error message. The same exact error occurs whether I am using CSVExport or CSVhelper.
Attempted Solutions:
My attempted solutions are mainly in regards to giving the app the permissions it needs to save. If an alternative like getting a different CSV package is better, I would take that advice too.
One solution I saw on StackOverflow linked to this page. The issue is I cannot load StorageFolder or Windows.Storage in my Xamarin app, it just won't recognize it and won't compile cause it's a missing load action.
Another solution I saw was changing your Capabilities in the Package.appxmanifest file and changing your Package header. I have done so, so mine looks like the following code sample. I need the internetClient and bluetooth and location for the app itself, so I added broadFilesystemaccess and even documents and pictures just to see if that would work too.
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap mp rescap">
...
<Capabilities>
<Capability Name="internetClient" />
<rescap:Capability Name="broadFileSystemAccess" />
<uap:Capability Name="documentsLibrary"/>
<uap:Capability Name="picturesLibrary" />
<DeviceCapability Name="bluetooth" />
<DeviceCapability Name="location"/>
</Capabilities>
Another solution was making sure the UWP app had permissions, which I went into system settings and allowed, so it should have full access now.
I am not sure where to go from here, so any advice about UWP or saving files within Xamarin UWP apps would be appreciated.
Based on your requirement, you could try to use the DependencyService feature of Xamarin.Forms.
DependencyService enables you to invoke native platform functionality from shared code. For your scenario, you could pass the stream of the file to the DependencyService first. then you could call the UWP FileSavePicker using DependencyService in your Forms app and save the stream as a file.
Here are some code snippets about how to implement the interface.
SaveFileAsync
public async Task SaveFileAsync(Stream data)
{
FileSavePicker savePicker = new FileSavePicker();
savePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
// Dropdown of file types the user can save the file as
savePicker.FileTypeChoices.Add("Text", new List<string>() { ".txt" });
savePicker.FileTypeChoices.Add("CSV", new List<string>() { ".csv" });
// Default file name if the user does not type one in or select a file to replace
savePicker.SuggestedFileName = "New Document";
StorageFile file = await savePicker.PickSaveFileAsync();
if (file!= null)
{
using (IRandomAccessStream dataStream= data.AsRandomAccessStream())
{
using (var reader = new DataReader(dataStream.GetInputStreamAt(0)))
{
await reader.LoadAsync((uint)dataStream.Size);
var buffer = new byte[(int)dataStream.Size];
reader.ReadBytes(buffer);
await Windows.Storage.FileIO.WriteBytesAsync(file, buffer);
}
}
}
}
ISaveFileServicecs interface
public interface ISaveFileServicecs
{
Task<Stream> SaveFileAsync(Stream stream);
}
Usage
await DependencyService.Get<ISaveFileServicecs>().SaveFileAsync(stream);

Passing values from native project to shared project Xamarin

Im currently facing an issue with using a 3rd party authenticator for my xamarin forms app. The code to execute has to be done natively in the platform project. The issue im facing is how to get the information(successful login, token, email etc) from the ios/android native project to the shared project for me to access it and continue the application. Below is an example of how the code looks below in the ios native project.
var client = new Auth0Client(new Auth0ClientOptions
{
Domain = "example.us.auth0.com",
ClientId = "123456789"
});
var loginResult = await client.LoginAsync();

Google service object for Google Calendar API

I am trying to use the Google Calendar API in .NET, specifically I am trying to get a list of events. According to the examples here, in different programming languages I need to create a 'service' object and an 'event' object. However, I can't find a clear explanation of what either of these objects is or how to initiate them. Does anyone have an explanation? Or can anyone provide any information or give me a link to where this is explained? It doesn't necessarily have to be in .NET
Here is the example in Java:
String pageToken = null;
do {
events = service.events().list('primary').setPageToken(pageToken).execute();
List<Event> items = events.getItems();
for (Event event : items) {
System.out.println(event.getSummary());
}
pageToken = events.getNextPageToken();
} while (pageToken != null);
Following the advice answered, I am getting the following error:
Could not load file or assembly 'Microsoft.Threading.Tasks.Extensions.Desktop, Version=1.0.16.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
Here is the code, the error occurs on the credentials = Await... line
Dim credential As UserCredential
Dim clientSecretsPath As String = Server.MapPath("~/App_Data/client_secret.json")
Dim scopes As IList(Of String) = New List(Of String)()
scopes.Add(CalendarService.Scope.Calendar)
Using stream = New System.IO.FileStream(clientSecretsPath, System.IO.FileMode.Open, System.IO.FileAccess.Read)
credential = Await GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets, scopes, "user", CancellationToken.None)
End Using
The problem with GoogleWebAuthorizationBroker is that it tries to launch a new instance of a web browser to go and get authorization where you have to click the "Grant" button.
Obviously if you're running a MVC project under IIS it's just going to get confused when the code tries to execute a web browser!
My solution:
Download the .net sample projects: https://code.google.com/p/google-api-dotnet-client/source/checkout?repo=samples
Build and run one of the projects relevant to you (Eg Calendar or Drive). Dont forget to include your client_secret.json file downloaded from the cloud console.
Run the project and it will open a new browser on your computer where you will have to click the "Grant" button. Do this once and then your MVC code will work because it will not try to open a web browser to grant the permissions.
I'm not aware of any other way to grant this permission to the SDK but it worked for me just great!
Good luck. This took me a good 5 hours to figure out.
Just had the same issue running VS2013 (using .net45 for my project):
After fetching the CalendarV3 API via NuGet you just have to manually add the reference to:
...packages\Microsoft.Bcl.Async.1.0.165\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll
to the project (because it is not inserted automatically via the NuGet-Script)!
That's it! Maybe #peleyal is correcting the script somewhen in future ;)
Remember that this sample is for Java. My recommendation is to do the following:
Take a look in our VB sample for the Calendar API which is available here
You should take a look also in other sample for C#, let's say Tasks API sample
Start a new project and add a NuGet reference to Google.Apis.Calednar.v3. Remember that it's prerelease version.
Your code should look like the following:
It's based on the 2 samples above, I didn't compile or test it but it should work.
UserCredential credential;
using (var stream = new System.IO.FileStream("client_secrets.json",
System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
new[] { CalendarService.Scope.Calendar },
"user", CancellationToken.None);
}
// Create the service.
var service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "YOUR APP NAME HERE",
});
var firstCalendar = (await service.CalendarList.List().ExecuteAsync()).Items().FirstOrDefault();
if (firstCalendar != null)
{
// Get all events from the first calendar.
var calEvents = await service.Events.List(firstCalendar.Id).ExecuteAsync();
// DO SOMETHING
var nextPage = calEvents.NextPage;
while (nextPage != null)
{
var listRequest = service.Events.List(firstCalendar.Id);
// Set the page token for getting the next events.
listRequest.PageToken = nextPage;
calEvents = await listRequest.EsecuteAsync();
// DO SOMETHING
nextPage = calEvents.NextPage;
}
}
I had the same error, and it was due to the app trying to launch the accept screen.
I first tried to get the vb.net example from google and ran that, which I did get to work, and change to my secret info, ran and got the accept screen. I then tried my app, and it still did not work.
I noticed that the dll was found here under my project installed from the nuget packages.
...packages\Microsoft.Bcl.Async.1.0.165\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll
but was not in the net45 dir. So I uninstalled the nuget packages (have to if changing the .net version) then changed my .net version for my project to 4.0 instead of 4.5, reinstalled the nuget packages, and then it worked!!

facebook c# sdk how to post to user's wall as application from wp7

I'd like to know, how can I use facebook c# sdk to post to user's wall from my wp7 app as application.
So I want to display message from FB application on users wall.
I have so far:
var app = new FacebookApp();
var parameters = new Dictionary<string, object>
{
{"access_token", accessToken},
{"appId", appId,
{"message", "TEST"}
};
var fbCB = new FacebookAsyncCallback(postResult);
app.PostAsync("me/feed", parameters, fbCB);
But this displays text on my wall as I wrote it, not like the application specified by appId.
app.PostAsync("friendId/feed", parameters, fbCB);
I would also suggest you to use the latest facebook c# sdk.

How do I upload some file into Azure blob storage without writing my own program?

I created an Azure Storage account. I have a 400 megabytes .zip file that I want to put into blob storage for later use.
How can I do that without writing code? Is there some interface for that?
Free tools:
Visual Studio 2010 -- install Azure tools and you can find the blobs in the Server Explorer
Cloud Berry Lab's CloudBerry Explorer for Azure Blob Storage
ClumpsyLeaf CloudXplorer
Azure Storage Explorer from CodePlex (try version 4 beta)
There was an old program called Azure Blob Explorer or something that no longer works with the new Azure SDK.
Out of these, I personally like CloudBerry Explorer the best.
The easiest way is to use Azure Storage PowerShell. It provided many commands to manage your storage container/blob/table/queue.
For your mentioned case, you could use Set-AzureStorageBlobContent which could upload a local file into azure storage as a block blob or page blob.
Set-AzureStorageBlobContent -Container containerName -File .\filename -Blob blobname
For details, please refer to http://msdn.microsoft.com/en-us/library/dn408487.aspx.
If you're looking for a tool to do so, may I suggest that you take a look at our tool Cloud Storage Studio (http://www.cerebrata.com/Products/CloudStorageStudio). It's a commercial tool for managing Windows Azure Storage and Hosted Service. You can also find a comprehensive list of Windows Azure Storage Management tools here: http://blogs.msdn.com/b/windowsazurestorage/archive/2010/04/17/windows-azure-storage-explorers.aspx
Hope this helps.
The StorageClient has this built into it. No need to write really anything:
var account = new CloudStorageAccount(creds, false);
var client = account.CreateCloudBlobClient();
var blob = client.GetBlobReference("/somecontainer/hugefile.zip");
//1MB seems to be a pretty good all purpose size
client.WriteBlockSizeInBytes = 1024;
//this sets # of parallel uploads for blocks
client.ParallelOperationThreadCount = 4; //normally set to one per CPU core
//this will break blobs up automatically after this size
client.SingleBlobUploadThresholdInBytes = 4096;
blob.UploadFile("somehugefile.zip");
I use Cyberduck to manage my blob storage.
It is free and very easy to use. It works with other cloud storage solutions as well.
I recently found this one as well: CloudXplorer
Hope it helps.
There is a new OpenSource tool provided by Microsoft :
Project Deco - Crossplatform Microsoft Azure Storage Account Explorer.
Please, check those links:
Download binaries: http://storageexplorer.com/
Source Code: https://github.com/Azure/deco
You can use Cloud Combine for reliable and quick file upload to Azure blob storage.
A simple batch file using Microsoft's AzCopy utility will do the trick. You can drag-and-drop your files on the following batch file to upload into your blob storage container:
upload.bat
#ECHO OFF
SET BLOB_URL=https://<<<account name>>>.blob.core.windows.net/<<<container name>>>
SET BLOB_KEY=<<<your access key>>>
:AGAIN
IF "%~1" == "" GOTO DONE
AzCopy /Source:"%~d1%~p1" /Dest:%BLOB_URL% /DestKey:%BLOB_KEY% /Pattern:"%~n1%~x1" /destType:blob
SHIFT
GOTO AGAIN
:DONE
PAUSE
Note that the above technique only uploads one or more files individually (since the Pattern flag is specified) instead of uploading an entire directory.
You can upload files to Azure Storage Account Blob using Command Prompt.
Install Microsoft Azure Storage tools.
And then Upload it to your account blob will CLI command:
AzCopy /Source:"filepath" /Dest:bloburl /DestKey:accesskey /destType:blob
Hope it Helps.. :)
You can upload large files directly to the Azure Blob Storage directly using the HTTP PUT verb, the biggest file I have tried with the code below is 4,6 Gb. You can do this in C# like this:
// write up to ChunkSize of data to the web request
void WriteToStreamCallback(IAsyncResult asynchronousResult)
{
var webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
var requestStream = webRequest.EndGetRequestStream(asynchronousResult);
var buffer = new Byte[4096];
int bytesRead;
var tempTotal = 0;
File.FileStream.Position = DataSent;
while ((bytesRead = File.FileStream.Read(buffer, 0, buffer.Length)) != 0
&& tempTotal + bytesRead < CHUNK_SIZE
&& !File.IsDeleted
&& File.State != Constants.FileStates.Error)
{
requestStream.Write(buffer, 0, bytesRead);
requestStream.Flush();
DataSent += bytesRead;
tempTotal += bytesRead;
File.UiDispatcher.BeginInvoke(OnProgressChanged);
}
requestStream.Close();
if (!AbortRequested) webRequest.BeginGetResponse(ReadHttpResponseCallback, webRequest);
}
void StartUpload()
{
var uriBuilder = new UriBuilder(UploadUrl);
if (UseBlocks)
{
// encode the block name and add it to the query string
CurrentBlockId = Convert.ToBase64String(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()));
uriBuilder.Query = uriBuilder.Query.TrimStart('?') + string.Format("&comp=block&blockid={0}", CurrentBlockId);
}
// with or without using blocks, we'll make a PUT request with the data
var webRequest = (HttpWebRequest)WebRequestCreator.ClientHttp.Create(uriBuilder.Uri);
webRequest.Method = "PUT";
webRequest.BeginGetRequestStream(WriteToStreamCallback, webRequest);
}
The UploadUrl is generated by Azure itself and contains a Shared Access Signature, this SAS URL says where the blob is to be uploaded to and how long time the security access (write access in your case) is given. You can generate a SAS URL like this:
readonly CloudBlobClient BlobClient;
readonly CloudBlobContainer BlobContainer;
public UploadService()
{
// Setup the connection to Windows Azure Storage
var storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
BlobClient = storageAccount.CreateCloudBlobClient();
// Get and create the container
BlobContainer = BlobClient.GetContainerReference("publicfiles");
}
string JsonSerializeData(string url)
{
var serializer = new DataContractJsonSerializer(url.GetType());
var memoryStream = new MemoryStream();
serializer.WriteObject(memoryStream, url);
return Encoding.Default.GetString(memoryStream.ToArray());
}
public string GetUploadUrl()
{
var sasWithIdentifier = BlobContainer.GetSharedAccessSignature(new SharedAccessPolicy
{
Permissions = SharedAccessPermissions.Write,
SharedAccessExpiryTime =
DateTime.UtcNow.AddMinutes(60)
});
return JsonSerializeData(BlobContainer.Uri.AbsoluteUri + "/" + Guid.NewGuid() + sasWithIdentifier);
}
I also have a thread on the subject where you can find more information here How to upload huge files to the Azure blob from a web page
The new Azure Portal has an 'Editor' menu option in preview when in the container view. Allows you to upload a file directly to the container from the Portal UI
I've used all the tools mentioned in post, and all work moderately well with block blobs. My favorite however is BlobTransferUtility
By default BlobTransferUtility only does block blobs. However changing just 2 lines of code and you can upload page blobs as well. If you, like me, need to upload a virtual machine image it needs to be a page blob.
(for the difference please see this MSDN article.)
To upload page blobs just change lines 53 and 62 of BlobTransferHelper.cs from
new Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob
to
new Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob
The only other thing to know about this app is to uncheck HELP when you first run the program to see the actual UI.
Check out this post Uploading to Azure Storage where it is explained how to easily upload any file via PowerShell to Azure Blob Storage.
You can use Azcopy tool to upload the required files to the azure default storage is block blob u can change pattern according to your requirement
Syntax
AzCopy /Source : /Destination /s
Try the Blob Service API
http://msdn.microsoft.com/en-us/library/dd135733.aspx
However, 400mb is a large file and I am not sure a single API call will deal with something of this size, you may need to split it and reconstruct using custom code.

Resources