So I'm trying to list the files in my S3 bucket to my winform in visual studio c#
static async Task ListingObjectAsync()
{
try
{
ListObjectsV2Request request = new ListObjectsV2Request
{
BucketName = bucketName
};
ListObjectsV2Response response;
do
{
response = await s3Client.ListObjectsV2Async(request);
foreach (S3Object entry in response.S3Objects)
{
string file = entry.Key;
ListViewItem item = new ListViewItem(file);
listView1.Items.Add(item);
}
} while (response.IsTruncated);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
But it says that "an object reference is required for a non static field"
Any tips on how to list files from S3 bucket to listview, datagrid or other forms?
Thank you!
P.S. I'm new to stack overflow so I'm sorry if my question format is wrong
remove the static from your method declaration:
async Task ListingObjectAsync(){...}
you cannot access instance variables from a static method
Related
I am having below method to copy data to destination storage blob
private static async Task MoveMatchingBlobsAsync(IEnumerable<ICloudBlob> sourceBlobRefs,
CloudBlobContainer sourceContainer,
CloudBlobContainer destContainer)
{
foreach (ICloudBlob sourceBlobRef in sourceBlobRefs)
{
if (sourceBlobRef.Properties.ContentType != null)
{
// Copy the source blob
CloudBlockBlob destBlob = destContainer.GetBlockBlobReference(sourceBlobRef.Name);
try
{
//exception throwed here - StartCopyAsync
await destBlob.StartCopyAsync(new Uri(GetSharedAccessUri(sourceBlobRef.Name, sourceContainer))); /
ICloudBlob destBlobRef = await destContainer.GetBlobReferenceFromServerAsync(sourceBlobRef.Name);
while (destBlobRef.CopyState.Status == CopyStatus.Pending)
{
Console.WriteLine($"Blob: {destBlobRef.Name}, Copied: {destBlobRef.CopyState.BytesCopied ?? 0} of {destBlobRef.CopyState.TotalBytes ?? 0}");
await Task.Delay(500);
destBlobRef = await destContainer.GetBlobReferenceFromServerAsync(sourceBlobRef.Name);
}
Console.WriteLine($"Blob: {destBlob.Name} Complete");
}
catch (Exception e)
{
Console.WriteLine($"Blob: {destBlob.Name} Copy Failed");
}
}
}
}
I am getting below exception, there is no more information
The requested operation is not allowed in the current state of the entity
What may be the cause?
Here is my method to collect blob from the source location
private static async Task<IEnumerable<ICloudBlob>> FindMatchingBlobsAsync(CloudBlobContainer blobContainer,string prefix, int maxrecords,int total)
{
List<ICloudBlob> blobList = new List<ICloudBlob>();
BlobContinuationToken token = null;
do
{
BlobResultSegment segment = await blobContainer.ListBlobsSegmentedAsync(prefix: prefix, useFlatBlobListing: true, BlobListingDetails.None, maxrecords, token, new BlobRequestOptions(), new OperationContext());
token = segment.ContinuationToken;
foreach (var item in segment.Results)
{
blobList.Add((ICloudBlob)item);
if (blobList.Count > total) // total record count is configured
token = null;
}
} while ( token != null);
return blobList;
}
Here is my GetSharedAccessUri method which returns Uri without any issue
private static string GetSharedAccessUri(string blobName, CloudBlobContainer container)
{
DateTime toDateTime = DateTime.Now.AddMinutes(60);
SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy
{
Permissions = SharedAccessBlobPermissions.Read,
SharedAccessStartTime = null,
SharedAccessExpiryTime = new DateTimeOffset(toDateTime)
};
CloudBlockBlob blob = container.GetBlockBlobReference(blobName);
string sas = blob.GetSharedAccessSignature(policy);
return blob.Uri.AbsoluteUri + sas;
}
This will iterate only 2 levels but not dynamically till the inner levels. I have blob in below hierarchy
--Container
--FolderA
--FolderAA
--FolderAA1
--File1.txt
--File2.txt
--FolderAA2
--File1.txt
--File2.txt
--FolderAA3
--FolderAB
--File8.txt
--FolderAC
--File9.txt
This hierarchy is dynamic
Additional Question: Is there any GUI tool to copy blob data to target storage account?
UPDATE
According to your description, I modified it in the official sample code. It is already possible to completely copy the data in one container to another account, and the code has been uploaded to Github.
To use this sample code, you need to modify the App.Config file. Formal use to the production environment needs to be perfected.
https://github.com/Jason446620/BlobContainerCopy
PRIVIOUS
You can refer to the code in this post for copy operation. If the solution in this post does not help you, please let me know and I will continue to follow up to help you solve the problem.
And u can download Azure Storage Explorer is the GUI tool to copy datas.
I think I've come across a bug in the CreateFolder command in the Reportingservices2010 SOAP API
The test scenario is I'm trying to create a folder (named Sales Dashboard) in the same Parent folder (lets say Sales) as a report also named Sales Dashboard.
The command completed with the "AlreadyExists" Exception when the folder does not already exist. It looks like the method isn't checking the catalog item type.
Here's my code:
public static void createFolders(string targetURL, string folderName, string parentPath, string description, string visible)
{
//Build Authentication
ReportingService2010 rs = new ReportingService2010();
rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
rs.Url = targetURL;
//Declare properties
Property descriptionProp = new Property();
Property visibleProp = new Property();
Property[] props = new Property[2];
descriptionProp.Name = "Description";
descriptionProp.Value = description;
visibleProp.Name = "Visible";
visibleProp.Value = visible;
props[0] = descriptionProp;
props[1] = visibleProp;
try
{
rs.CreateFolder(folderName, parentPath, props);
}
catch(Exception ex)
{
if(ex.Message.Contains("AlreadyExists"))
{
//do nothing?
}
else
{
throw;
}
}
}
I wanted to see if I could contribute a fix but there's no GitHub repo for the C# SSRS stuff. Any thought's on a workaround?
The API is returning the correct error since this is a restriction of Reporting Services in general: items within the same folder must have unique names (regardless of item type).
I'm using HttpClient to POST a user created string to a server API and get the result. Previously I used a TextBox to allow the user to enter the string but I wanted pretty colours so I tried to replace the TextBox with a RichEditBox but failed miserably. When using the TextBox everything worked fine but when using the RichEditBox I get an "Access denied" message. I get the text from the RichEditBox with the Document.GetText method. I can get it to work by either inserting a static string in the place where I get the text or in the place where I send the string into a FormUrlEncodedContent. The string is edited before and after adding the text from the RichEditBox, and sent to another method.
TL:DR: Sending a string from a TextBox with a HttpClient using POST works but not when replacing the TextBox with a RichEditBox.
Here's the full error message:
System.UnauthorizedAccessException: 'Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))'
Does anyone have a solution or an explanation to why this is happening?
Edit
Code sample:
private async void RichEditBox_KeyUp(object sender, KeyRoutedEventArgs e)
{
if (e.Key == VirtualKey.Enter)
{
await RunCode(); //The error points to this line
}
}
private async void RunCode()
{
string code = CodeBefore;
foreach (RichEditBox tb in editStack.Children) //If I comment out the foreach loop I don't get any errors
{
if (tb.Tag.ToString() == "input")
{
tb.Document.GetText(Windows.UI.Text.TextGetOptions.None, out string thisLine);
code += thisLine;
}
}
code += CodeAfter;
await RunCSharp(code);
}
private async Task<Code> RunCSharp(string code)
{
Code re = new Code();
using (HttpClient client = new HttpClient())
{
FormUrlEncodedContent content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("LanguageChoiceWrapper", "1"),
new KeyValuePair<string, string>("Program", code), //If I replace code with a string I don't get any errors
new KeyValuePair<string, string>("ShowWarnings", "false")
});
try
{
HttpResponseMessage msg = await client.PostAsync("http://mywebaddress.com/run", content);
re = JsonConvert.DeserializeObject<Code>(await msg.Content.ReadAsStringAsync());
}
catch { }
}
return re;
}
Trying to figure out why this isn't working, the list is to retrieve photos using the combobox item (which lists local HDDs root address as items) when selected that item it is converted into a string and supposed to be used as a path for the GetFiles Method but screws up on the (string path = ) line when running, I get "object reference not set to instance of an object" much appreciated If someone could tell me what is going wrong
public List<Photos> LoadImages ///List Retrieves and Loads Photos
{
get
{
List<Photos> Image = new List<Photos>();
string path = HDDSelectionBox.SelectedItem.ToString(); //ComboBox SelectedItem Converted To String As Path
foreach (string filename in Directory.GetFiles(path, "*jpg"))
{
try
{
Image.Add( //Add To List
new Photos(
new BitmapImage(
new Uri(filename)),
System.IO.Path.GetFileNameWithoutExtension(filename)));
}
catch { } //Skips Any Image That Isn't Image/Cant Be Loaded
}
return Image;
}
}
You should put . before the file extension in the line:
Directory.GetFiles(path, "*.jpg")
You also need to check if HDDSelectionBox.SelectedItem is not null:
public List<Photos> LoadImages ///List Retrieves and Loads Photos
{
get
{
List<Photos> images = new List<Photos>();
if (HDDSelectionBox.SelectedItem != null)
{
string path = HDDSelectionBox.SelectedItem.ToString(); //ComboBox SelectedItem Converted To String As Path
foreach (string filename in Directory.GetFiles(path, "*.jpg"))
{
try
{
images.Add( //Add To List
new Photos(
new BitmapImage(
new Uri(filename)),
System.IO.Path.GetFileNameWithoutExtension(filename)));
}
catch { } //Skips Any Image That Isn't Image/Cant Be Loaded
}
}
return images;
}
}
Also, this is probably better suited to a method rather than a property as it does quite a lot of processing...
I've created a Standard SharePoint 2013 Event Receiver on a custom list.
Watched Event = "ItemAdded".
Later in my code I need to retrieve the attachments of the list item in the same order as the user inserted them. But unfortunately it seems that SharePoint does not do this by Default.
Example:
The User creates a list item and attach the following files
Picture_front.jpg
Picture_back.png
Picture_231.jpg
Now in my Event Receiver it is possible that I first get 'Picture_back' then 'Picture_front'... or in any other order.
How can I retrieve the attachments in the same order as they have been attached to the list item?
I tried to use the SPFile Property 'TimeCreated' but this is also not working... They got the same timestamp :( (also if I am using 'Ticks')
Any ideas or I am doing something wrong?
Here is my Code:
public override void ItemAdded(SPItemEventProperties properties)
{
SPAttachmentCollection attachments = properties.ListItem.Attachments;
if (attachments.Count > 0)
{
int p = 1;
Dictionary<string, string> attachementDict = new Dictionary<string, string>();
try
{
foreach (string attachement in attachments)
{
SPFile attachementFile = properties.ListItem.ParentList.ParentWeb.GetFile(properties.ListItem.Attachments.UrlPrefix + attachement);
string imageUrlPath = properties.WebUrl + attachementFile.ServerRelativeUrl;
string imageTimestamp = attachementFile.TimeCreated.Ticks.ToString();
// This Dict is used lator for sorting
// but at the Moment I get here the error that the same key already exists because of the same timestamp of the files :(
attachementDict.Add(imageTimestamp, imageUrlPath);
}
}
catch (Exception ex)
{
// SPLog
}
}
here my code ..i hope it help you!
try
{
string strUrl = SPContext.Current.Site.Url + "/" + subSite;
using (SPSite Site = new SPSite(strUrl))
{
using (SPWeb Web = Site.OpenWeb())
{
SPList List = Web.Lists[listName];
SPListItem item = List.GetItemById(ID);
foreach (String attachmentname in item.Attachments)
{
AnnouncementsCommon objAnnouncementsCommon = new AnnouncementsCommon();
String attachmentAbsoluteURL = item.Attachments.UrlPrefix + attachmentname;
objAnnouncementsCommon.AttachmentName = attachmentname;
objAnnouncementsCommon.AttachmentURL = attachmentAbsoluteURL;
lstAnnouncementsCommon.Add(objAnnouncementsCommon);
}
}
}
}
catch (Exception Exc)
{
Microsoft.Office.Server.Diagnostics.PortalLog.LogString("SSC DAL Exception Occurred: {0} || {1}", Exc.Message, Exc.StackTrace);
}
return lstAnnouncementsCommon;
}
As an alternative approach you could use your receiver to store the attachments in a picture library and add two fields to this library: a lookup column to your original custom list item and an option column with "default", "front view", "back view" (or similar).
One advantage is that you can easily update your images in the future and another is that SharePoint automatically creates two preview miniatures in convenient sizes for your images which allows you to reduce bandwidth.