Creating C#/.net application that gets services names from AWS using the cluster name. With the AWS .net SDK
Able to retrieve cluster names and save them in a list of strings:
AmazonECSClient client = new AmazonECSClient();
ListClustersRequest listClusterREquest = new ListClustersRequest();
var responseClusterList = await client.ListClustersAsync(listClusterREquest);
List<string> clusterArns = responseClusterList.ClusterArns;
Now trying to retrieve the list of services using the cluster names. I am having issues saving each response back to a list named serviceArns. It only saves the last response to the list called serviceArns. There should be about 20 responses saved to the list.
ListServicesRequest listRequest = new ListServicesRequest();
List<string> serviceArns = null;
ListServicesResponse responsethree = new ListServicesResponse();
foreach (var item in clusterArns)
{
listRequest.Cluster = item;
ListServicesResponse listResponse = await client.ListServicesAsync(listRequest);
serviceArns = listResponse.ServiceArns;
};
You should intialise the list at the start and add elements as needed be. Currently with each iteration, the list gets set, where it should be adding it instead.
ListServicesRequest listRequest = new ListServicesRequest();
List<string> serviceArns = new();
ListServicesResponse responsethree = new ListServicesResponse();
foreach (var item in clusterArns)
{
listRequest.Cluster = item;
ListServicesResponse listResponse = await client.ListServicesAsync(listRequest);
serviceArns.AddRange(listResponse.ServiceArns);
};
Related
I have an Active Directory group with more than 3000 members in it. I want to retrieve all those members from that group using the LDAP connection. I tried using the below snippet but it is providing one 1-1499 members from the group. Is there is any other way to achieve the same
LdapConnection connection = new LdapConnection(********);
NetworkCredential cred = new NetworkCredential(********, ********, ********);
connection.Credential = cred;
List<SearchResponse> results = new List<SearchResponse>();
SearchRequest request = new SearchRequest("***********", "(objectClass=group)", System.DirectoryServices.Protocols.SearchScope.Subtree, new string[] {"member" });
PageResultRequestControl prc = new PageResultRequestControl(1000);
SearchOptionsControl soc = new SearchOptionsControl(System.DirectoryServices.Protocols.SearchOption.DomainScope);
request.Controls.Add(prc);
request.Controls.Add(soc);
while (true)
{
SearchResponse response = connection.SendRequest(request) as SearchResponse;
foreach (DirectoryControl control in response.Controls)
{
if (control is PageResultResponseControl)
{
prc.Cookie = ((PageResultResponseControl)control).Cookie;
break;
}
}
foreach (var item in response.Entries[0].Attributes["member"].GetValues(typeof(String)))
{
var t = item;
}
results.Add(response);
}
Appears that you are hitting the MaxValRange limits.
MaxValRange value controls the number of values that are returned for an attribute of an object, independent of how many attributes that object has, or of how many objects were in the search result.
I do not do C# but We have a sample in Java code that may be helpful.
I'm getting a print queue for various printers installed locally by doing:
var queueName = "Myprinterqueue";
using (var ps = new PrintServer())
using (var pq = ps.GetPrintQueue(queueName))
{
pq.Refresh();
var status = pq.QueueStatus;
var jobs = pq.NumberOfJobs;
var averagePagesPerMinute = pq.AveragePagesPerMinute;
}
Status and NumberOfJobs are retrieved correctly. But many other print capabilities, eg. AveragePagesPerMinute, are always empty or 0.
Why is this?
I'm using the AWS SDK with C# in Visual Studio 2017, and have a prototype working which launches a Fargate service in ECS. As part of the setup, you instantiate a CreateServiceRequest object which requires a NetworkConfiguration.AwsVpcConfiguration setting with SecurityGroups and Subnets.
var request = new CreateServiceRequest();
request.ServiceName = "myService";
request.TaskDefinition = "myTask"; // family[:revision] of the task definition to use
request.ClientToken = Guid.NewGuid().ToString().Replace("-", ""); // max 32 characters!
request.Cluster = "default";
request.DesiredCount = 1;
request.LaunchType = LaunchType.FARGATE;
request.DeploymentConfiguration = new DeploymentConfiguration
{
MaximumPercent = 100,
MinimumHealthyPercent = 50
};
// configure the network and security groups for the task
List<string> securityGroups = new List<string>();
securityGroups.Add("sg-123456");
List<string> subnets = new List<string>();
subnets.Add("subnet-9b36aa97");
request.NetworkConfiguration = new NetworkConfiguration
{
AwsvpcConfiguration = new AwsVpcConfiguration
{
AssignPublicIp = AssignPublicIp.ENABLED,
SecurityGroups = securityGroups,
Subnets = subnets
}
};
When I configure a service manually via the AWS Console, they display a list of subnets from which to choose. So, I'm wondering how I might programmatically retrieve that list of subnets which are available in our VPC.
I'm searching their SDK documentation for possible solutions, any pointers to their docs or examples is appreciated!
Take a look at EC2Client, you'll find a lot of VPC-related APIs are associated with the EC2 service. Specifically check out AmazonEC2Client.DescribeSubnets(DescribeSubnetsRequest), method documentation here:
Request
Amazon.EC2.Model.DescribeSubnetsRequest
Response
Amazon.EC2.Model.DescribeSubnetsResponse
Response contains a list of Amazon.EC2.Model.Subnet that you will retrieve string property SubnetId from, when deciding which subnet to pass on to your Fargate request.
Example Usage (From the linked documentation):
var response = client.DescribeSubnets(new DescribeSubnetsRequest
{
Filters = new List<filter> {
new Filter {
Name = "vpc-id",
Values = new List<string> {
"vpc-a01106c2"
}
}
}
});
List<subnet> subnets = response.Subnets;
Further Reading
AWS Documentation - EC2Client - Search this document for 'DescribeSubnets' to find async variants of this SDK method.
I have a SharePoint List to which I'm adding new ListItems using the Client Object Model.
Adding ListItems is not a problem and works great.
Now I want to add attachments.
I'm using the SaveBinaryDirect in the following manner:
File.SaveBinaryDirect(clientCtx, url.AbsolutePath + "/Attachments/31/" + fileName, inputStream, true);
It works without any problem as long as the item that I'm trying to add the attachment to, already has an attachment that was added through the SharePoint site and not using the Client Object Model.
When I try to add an attachment to a item that doesnt have any attachments yet, I get the following errors (both happen but not with the same files - but those two messages appear consistently):
The remote server returned an error: (409) Conflict
The remote server returned an error: (404) Not Found
I figured that maybe I need to create the attachment folder first for this item.
When I try the following code:
clientCtx.Load(ticketList.RootFolder.Folders);
clientCtx.ExecuteQuery();
clientCtx.Load(ticketList.RootFolder.Folders[1]); // 1 -> Attachment folder
clientCtx.Load(ticketList.RootFolder.Folders[1].Folders);
clientCtx.ExecuteQuery();
Folder folder = ticketList.RootFolder.Folders[1].Folders.Add("33");
clientCtx.ExecuteQuery();
I receive an error message saying:
Cannot create folder "Lists/Ticket System/Attachment/33"
I have full administrator rights for the SharePoint site/list.
Any ideas what I could be doing wrong?
Thanks, Thorben
I struggled for a long time with this problem too, so I thought I'd post a complete code sample showing how to successfully create a list item and add an attachment.
I am using the Client Object API to create the list item, and the SOAP web service to add the attachment. This is because, as noted in other places on the web, the Client Object API can only be used to add attachments to an item where the item's upload directory already exists (eg. if the item already has an attachment). Else it fails with a 409 error or something. The SOAP web service copes with this OK though.
Note that another thing I had to overcome was that even though I added the SOAP reference using the following URL:
https://my.sharepoint.installation/personal/test/_vti_bin/lists.asmx
The URL that VS actually added to the app.config was:
https://my.sharepoint.installation/_vti_bin/lists.asmx
I had to manually change the app.config back to the correct URL, else I would get the error:
List does not exist.
The page you selected contains a list that does not exist. It may have been deleted by another user.
0x82000006
Here is the code:
void CreateWithAttachment()
{
const string listName = "MyListName";
// set up our credentials
var credentials = new NetworkCredential("username", "password", "domain");
// create a soap client
var soapClient = new ListsService.Lists();
soapClient.Credentials = credentials;
// create a client context
var clientContext = new Microsoft.SharePoint.Client.ClientContext("https://my.sharepoint.installation/personal/test");
clientContext.Credentials = credentials;
// create a list item
var list = clientContext.Web.Lists.GetByTitle(listName);
var itemCreateInfo = new ListItemCreationInformation();
var newItem = list.AddItem(itemCreateInfo);
// set its properties
newItem["Title"] = "Created from Client API";
newItem["Status"] = "New";
newItem["_Comments"] = "here are some comments!!";
// commit it
newItem.Update();
clientContext.ExecuteQuery();
// load back the created item so its ID field is available for use below
clientContext.Load(newItem);
clientContext.ExecuteQuery();
// use the soap client to add the attachment
const string path = #"c:\temp\test.txt";
soapClient.AddAttachment(listName, newItem["ID"].ToString(), Path.GetFileName(path),
System.IO.File.ReadAllBytes(path));
}
Hope this helps someone.
I have discussed this question with Microsoft. Looks like that only one way to create attachments remotely is List.asmx web service. I have tried to create this subfolder also and with no success.
With Sharepoint 2010 there was no way to upload a first attachment to a list item using the COM. The recommendation was to use the Lists web service inmstead.
With Sharepoint 2013 it works.
AttachmentCreationInformation newAtt = new AttachmentCreationInformation();
newAtt.FileName = "myAttachment.txt";
// create a file stream
string fileContent = "This file is was ubloaded by client object meodel ";
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
byte[] buffer = enc.GetBytes(fileContent);
newAtt.ContentStream = new MemoryStream(buffer);
// att new item or get existing one
ListItem itm = list.GetItemById(itemId);
ctx.Load(itm);
// do not execute query, otherwise a "version conflict" exception is rised, but the file is uploaded
// add file to attachment collection
newAtt.ContentStream = new MemoryStream(buffer);
itm.AttachmentFiles.Add(newAtt);
AttachmentCollection attachments = itm.AttachmentFiles;
ctx.Load(attachments);
ctx.ExecuteQuery();
// see all attachments for list item
// this snippet works if the list item has no attachments
This method is used in http://www.mailtosharepoint.net/
It reflects rather poorly on the Microsoft SharePoint team for not coming forward with an acknowledgement of the issue and a usable suggestion on how to resolve it. Here is how I dealt with it:
I am using the new SharePoint 2010 managed client that ships with the product. Hence, I already have a SharePoint ClientContext with credentials. The following function adds an attachment to a list item:
private void SharePoint2010AddAttachment(ClientContext ctx,
string listName, string itemId,
string fileName, byte[] fileContent)
{
var listsSvc = new sp2010.Lists();
listsSvc.Credentials = _sharePointCtx.Credentials;
listsSvc.Url = _sharePointCtx.Web.Context.Url + "_vti_bin/Lists.asmx";
listsSvc.AddAttachment(listName, itemId, fileName, fileContent);
}
The only prerequisite for the code above is to add to the project (I used Visual Studio 2008) a _web_reference_ I called sp2010 which is created from the URL of: http:///_vti_bin/Lists.asmx
Bon Chance...
HTML:
<asp:FileUpload ID="FileUpload1" runat="server" AllowMultiple="true" />
Event in code behind :
protected void UploadMultipleFiles(object sender, EventArgs e)
{
Common.UploadDocuments(Common.getContext(new Uri(Request.QueryString["SPHostUrl"]),
Request.LogonUserIdentity), FileUpload1.PostedFiles, new CustomerRequirement(), 5);
}
public static List<string> UploadDocuments<T>(ClientContext ctx,IList<HttpPostedFile> selectedFiles, T reqObj, int itemID)
{
List<Attachment> existingFiles = null;
List<string> processedFiles = null;
List<string> unProcessedFiles = null;
ListItem item = null;
FileStream sr = null;
AttachmentCollection attachments = null;
byte[] contents = null;
try
{
existingFiles = new List<Attachment>();
processedFiles = new List<string>();
unProcessedFiles = new List<string>();
//Get the existing item
item = ctx.Web.Lists.GetByTitle(typeof(T).Name).GetItemById(itemID);
//get the Existing attached attachments
attachments = item.AttachmentFiles;
ctx.Load(attachments);
ctx.ExecuteQuery();
//adding into the new List
foreach (Attachment att in attachments)
existingFiles.Add(att);
//For each Files which user has selected
foreach (HttpPostedFile postedFile in selectedFiles)
{
string fileName = Path.GetFileName(postedFile.FileName);
//If selected file not exist in existing item attachment
if (!existingFiles.Any(x => x.FileName == fileName))
{
//Added to Process List
processedFiles.Add(postedFile.FileName);
}
else
unProcessedFiles.Add(fileName);
}
//Foreach process item add it as an attachment
foreach (string path in processedFiles)
{
sr = new FileStream(path, FileMode.Open);
contents = new byte[sr.Length];
sr.Read(contents, 0, (int)sr.Length);
var attInfo = new AttachmentCreationInformation();
attInfo.FileName = Path.GetFileName(path);
attInfo.ContentStream = sr;
item.AttachmentFiles.Add(attInfo);
item.Update();
}
ctx.ExecuteQuery();
}
catch (Exception ex)
{
throw ex;
}
finally
{
existingFiles = null;
processedFiles = null;
item = null;
sr = null;
attachments = null;
contents = null;
ctx = null;
}
return unProcessedFiles;
}
I've used and tried this one on my CSOM (SharePoint Client Object Model) application and it works for me
using (ClientContext context = new ClientContext("http://spsite2010"))
{
context.Credentials = new NetworkCredential("admin", "password");
Web oWeb = context.Web;
List list = context.Web.Lists.GetByTitle("Tasks");
CamlQuery query = new CamlQuery();
query.ViewXml = "<View><Where><Eq><FieldRef Name = \"Title\"/><Value Type=\"String\">New Task Created</Value></Eq></Where></View>";
ListItemCollection listItems = list.GetItems(query);
context.Load(listItems);
context.ExecuteQuery();
FileStream oFileStream = new FileStream(#"C:\\sample.txt", FileMode.Open);
string attachmentpath = "/Lists/Tasks/Attachments/" + listItems[listItems.Count - 1].Id + "/sample.txt";
Microsoft.SharePoint.Client.File.SaveBinaryDirect(context, attachmentpath, oFileStream, true);
}
Note: Only works if item folder has been created already
I am really looking for either a small code snippet.
I have a C# console app that I will use to somehow add list items to my custom list. I have created a custom content type too. So not sure if I need to create an C# class from this content type too. Perhaps not.
I think these both blog post should help you solving your problem.
http://blog.the-dargans.co.uk/2007/04/programmatically-adding-items-to.html
http://asadewa.wordpress.com/2007/11/19/adding-a-custom-content-type-specific-item-on-a-sharepoint-list/
Short walk through:
Get a instance of the list you want to add the item to.
Add a new item to the list:
SPListItem newItem = list.AddItem();
To bind you new item to a content type you have to set the content type id for the new item:
newItem["ContentTypeId"] = <Id of the content type>;
Set the fields specified within your content type.
Commit your changes:
newItem.Update();
To put it simple you will need to follow the step.
You need to reference the Microsoft.SharePoint.dll to the application.
Assuming the List Name is Test and it has only one Field "Title" here is the code.
using (SPSite oSite=new SPSite("http://mysharepoint"))
{
using (SPWeb oWeb=oSite.RootWeb)
{
SPList oList = oWeb.Lists["Test"];
SPListItem oSPListItem = oList.Items.Add();
oSPListItem["Title"] = "Hello SharePoint";
oSPListItem.Update();
}
}
Note that you need to run this application in the Same server where the SharePoint is installed.
You dont need to create a Custom Class for Custom Content Type
You can create an item in your custom SharePoint list doing something like this:
using (SPSite site = new SPSite("http://sharepoint"))
{
using (SPWeb web = site.RootWeb)
{
SPList list = web.Lists["My List"];
SPListItem listItem = list.AddItem();
listItem["Title"] = "The Title";
listItem["CustomColumn"] = "I am custom";
listItem.Update();
}
}
Using list.AddItem() should save the lists items being enumerated.
This is how it was on the Microsoft site, with me just tweaking the SPSite and SPWeb since these might vary from environment to environment and it helps not to have to hard-code these:
using (SPSite oSiteCollection = new SPSite(SPContext.Current.Site.Url))
{
using (SPWeb oWeb = oSiteCollection.OpenWeb(SPContext.Current.Web))
{
SPList oList = oWeb.Lists["Announcements"];
// You may also use
// SPList oList = oWeb.GetList("/Lists/Announcements");
// to avoid querying all of the sites' lists
SPListItem oListItem = oList.Items.Add();
oListItem["Title"] = "My Item";
oListItem["Created"] = new DateTime(2004, 1, 23);
oListItem["Modified"] = new DateTime(2005, 10, 1);
oListItem["Author"] = 3;
oListItem["Editor"] = 3;
oListItem.Update();
}
}
Source:
SPListItemClass (Microsoft.SharePoint). (2012). Retrieved February 22, 2012, from http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splistitem.aspx.
I had a similar problem and was able to solve it by following the below approach (similar to other answers but needed credentials too),
1- add Microsoft.SharePointOnline.CSOM by tools->NuGet Package Manager->Manage NuGet Packages for solution->Browse-> select and install
2- Add "using Microsoft.SharePoint.Client; "
then the below code
string siteUrl = "https://yourcompany.sharepoint.com/sites/Yoursite";
SecureString passWord = new SecureString();
var password = "Your password here";
var securePassword = new SecureString();
foreach (char c in password)
{
securePassword.AppendChar(c);
}
ClientContext clientContext = new ClientContext(siteUrl);
clientContext.Credentials = new SharePointOnlineCredentials("Username#domain.nz", securePassword);/*passWord*/
List oList = clientContext.Web.Lists.GetByTitle("The name of your list here");
ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation();
ListItem oListItem = oList.AddItem(itemCreateInfo);
oListItem["PK"] = "1";
oListItem["Precinct"] = "Mangere";
oListItem["Title"] = "Innovation";
oListItem["Project_x0020_Name"] = "test from C#";
oListItem["Project_x0020_ID"] = "ID_123_from C#";
oListItem["Project_x0020_start_x0020_date"] = "2020-05-01 01:01:01";
oListItem.Update();
clientContext.ExecuteQuery();
Remember that your fields may be different with what you see, for example in my list I see "Project Name", while the actual value is "Project_x0020_ID". How to get these values (i.e. internal filed values)?
A few approaches:
1- Use MS flow and see them
2- https://mstechtalk.com/check-column-internal-name-sharepoint-list/ or https://sharepoint.stackexchange.com/questions/787/finding-the-internal-name-and-display-name-for-a-list-column
3- Use a C# reader and read your sharepoint list
The rest of operations (update/delete):
https://learn.microsoft.com/en-us/previous-versions/office/developer/sharepoint-2010/ee539976(v%3Doffice.14)