Create and Manage Sharepoint DocumentSet with MS Graph - c#

I can't find any way to create a documentset in Sharepoint Library using MS graph. Is there a way to do it? any help is mostly appreciated

AFAIK, there is no straight forward API today that you can leverage to achieve this.
Being said that, you can try this workout and see if this helps -
Get document library's drive id.
GET https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${listId}?$expand=drive
Create folder.
POST https://graph.microsoft.com/v1.0/drives/${library.drive.id}/root/children
Request body
{
"name": "New Folder name",
"folder": {},
"#microsoft.graph.conflictBehavior": "rename"
}
Get SharePoint item id for created folder.
GET https://graph.microsoft.com/v1.0/sites/${siteId}/drives/${library.drive.id}/items/${folder.id}?expand=sharepointids
4.Update the item in the Document Library so that it updates to the desired Document Set.
PATCH https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${listId}/items/${sharepointIds.listItemId}
Request body
{
"contentType": {
"id": "content-type-id-of-the-document-set"
},
"fields": {
//fields that you wish to set
}
}

I was able to complete this in the following way, sorry for not updating eariler:
Vars:
SpURL = "site.sharepoint.com";
SiteURL = "/sites/myTestSite";
LibraryName = "Library";
ContentType = "mycontenttype";
1- Get Site ID By Path:
var scopes = new string[] { ISD.MicrosoftGraph.Constants.ScopeDefault };
var client = GraphServiceClientFactory.GetAuthenticatedGraphClient(() => AcquireAppToken(scopes), "https://graph.microsoft.com/beta");
var site = await client.Sites.GetByPath(siteURL, spURL).Request().GetAsync();
return site.Id;
2- Drive ID by Path:
var scopes = new string[] { ISD.MicrosoftGraph.Constants.ScopeDefault };
var client = GraphServiceClientFactory.GetAuthenticatedGraphClient(() => AcquireAppToken(scopes), "https://graph.microsoft.com/beta");
var request = client.Sites[siteID].Drives.Request();
var result = await request.GetAsync();
//.Filter is not working here for some reasone
var filter = result?.Where(x => x.Name.Contains(LibraryName)).ToList();
if (filter.Count > 0) {
return filter.First().Id;
}
else {
return "";
}
3- Get List ID:
var scopes = new string[] { ISD.MicrosoftGraph.Constants.ScopeDefault };
var client = GraphServiceClientFactory.GetAuthenticatedGraphClient(() => AcquireAppToken(scopes), "https://graph.microsoft.com/beta");
var request = client.Sites[siteID].Lists.Request().Filter($"displayName eq '{ListName}'");
var result = await request.GetAsync();
return result.First().Id;
List ID:
var scopes = new string[] { ISD.MicrosoftGraph.Constants.ScopeDefault };
var client = GraphServiceClientFactory.GetAuthenticatedGraphClient(() => AcquireAppToken(scopes), "https://graph.microsoft.com/beta");
var request = client.Sites[siteID].Lists.Request().Filter($"displayName eq '{ListName}'");
var result = await request.GetAsync();return result.First().Id;
Add new folder:
var scopes = new string[] { ISD.MicrosoftGraph.Constants.ScopeDefault };
var client = GraphServiceClientFactory.GetAuthenticatedGraphClient(() => AcquireAppToken(scopes), "https://graph.microsoft.com/beta");
var folder = new DriveItem
{
Name = foldername,
Folder = new Microsoft.Graph.Folder(),
AdditionalData = new Dictionary<string, object>()
{
{"#microsoft.graph.conflictBehavior", "rename"}
},
};
var folderObj = await client.Drives[driveID].Root.Children.Request().AddAsync(folder);
return folderObj.Id;
//Save folderID from the above return
contentType ID:
var scopes = new string[] { ISD.MicrosoftGraph.Constants.ScopeDefault };
var client = GraphServiceClientFactory.GetAuthenticatedGraphClient(() => AcquireAppToken(scopes), "https://graph.microsoft.com/beta");
var request = client.Sites[siteID].Lists[listID].ContentTypes.Request().Filter($"name eq '{contentTypeName}'");
var result = await request.GetAsync();
return result.First().Id;
List Item ID:
var scopes = new string[] { ISD.MicrosoftGraph.Constants.ScopeDefault };
var client = GraphServiceClientFactory.GetAuthenticatedGraphClient(() => AcquireAppToken(scopes), "https://graph.microsoft.com/beta");
var request = client.Sites[siteID].Drives[driveID].Items[folderID].Request().Select("sharepointIds");
var result = await request.GetAsync();
return result.SharepointIds.ListItemId;
Set folder content type and Proprities:
var scopes = new string[] { ISD.MicrosoftGraph.Constants.ScopeDefault };
var client = GraphServiceClientFactory.GetAuthenticatedGraphClient(() => AcquireAppToken(scopes), "https://graph.microsoft.com/beta");
var listItem = new Microsoft.Graph.ListItem
{
Fields = new FieldValueSet
{
AdditionalData = new Dictionary<string, object>()
{
{"Country", "Palestine"},
{ "My_x0020_Field", "2000"}//Custom field with spaces
}
}
, ContentType = new ContentTypeInfo() {
Id = "0x5465424879454894654564654F300A1C2CDC00E306F9F19B9654654654654" //this is a sample content type id acquired in step 6
}
};
var request = client.Sites[siteID].Lists[listID].Items[listItemID].Request();
var result = await request.UpdateAsync(listItem);
Hope this helps someone

Related

how to form comma separated string from bson array using asp.net core 2.2?

I have an api based on asp.net core 2.2 in which i am building up an array of ips(strings type) like this
[HttpGet ("{nsp}/geolocation")]
[ResponseCache (Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public async Task<dynamic> getLocation (string nsp) {
nsp = "/"+nsp;
// string ipInfoBaseUrl = "http://ip-api.com/json/";
string baseUrl = "http://ip-api.com/batch";
// string userIpAddress = "197.157.194.90";
// string ipUrl = ipInfoBaseUrl + userIpAddress;
// var client = _httpClientFactory.CreateClient();
// var result = await client.PostAsync(baseUrl,new StringContent(JsonConvert.SerializeObject(finals), System.Text.Encoding.UTF8, "application/json"));
// // var final = Newtonsoft.Json.JsonConvert.DeserializeObject<UserLocation>(result);
// Console.WriteLine(finals+" --result-----");
// return Ok(result);
var match = new BsonDocument ();
var group = new BsonDocument ();
var project = new BsonDocument ();
var sort = new BsonDocument ();
var addFields = new BsonDocument ();
var pipeline = new [] { new BsonDocument () };
/* #Aggregation : Stage-1 */
match = new BsonDocument ("$match",
new BsonDocument {
{
"nsp" , nsp
}
});
/* #Aggregation : Stage-2 */
group = new BsonDocument("$group",
new BsonDocument
{ {
"_id", "null"
},
{ "geoLocations",
new BsonDocument("$addToSet", "$visitor.ip")
}
});
/* #Aggregation : Stage-3 */
project = new BsonDocument ("$project", new BsonDocument { { "_id", 0 }});
pipeline = new [] { match, group,project};
var list = await DbService.tickets.AggregateAsync<BsonDocument> (pipeline, new AggregateOptions { UseCursor = true, BatchSize = batchCount });
while (await list.MoveNextAsync ()) {
var list_real = new List<BsonValue> ();
foreach (var data in list.Current.ToArray ()) {
list_real.Add (data);
}
return list_real.ToJson ();
}
return new BsonArray ().ToJson ();
}
It is returning result like this
[
{
" geoLocations": [
"122.8.208.9",
"196.62.107.243",
"182.188.38.219",
"39.50.244.198",
"39.51.40.251",
"103.20.134.56",
"103.228.156.83",
"202.143.125.21",
"196.62.151.47",
"45.116.232.50",
"39.57.128.75",
"103.18.8.60",
"202.143.125.20",
"182.190.252.96",
"119.153.56.2",
"46.101.89.227",
"196.194.172.211",
"192.168.20.186",
"64.233.173.146",
"104.236.195.147",
"39.50.156.242",
"103.255.5.58"
]
}
]
How can i get comma separated string from this result like
"111.92.158.82","202.142.168.162","122.8.157.172",.....
From very first i am getting all ips from all documents from my collection and forming an array of ips.But my ultimate goal is to form a comma separated string from that array because i have to pass that comma separated string of ips into an api to get ips locations.
I am using asp.net core and c#. How can i achieve this?
Assuming you want a single comma-separated result string containing all IP addresses, replace the method signature with IEnumerable<string>, and replace the bottom of the method with. Just use whatever you need for your result and get rid of the rest.
var list = await DbService.tickets.AggregateAsync<BsonDocument> (pipeline,
new AggregateOptions
{
UseCursor = true,
BatchSize = batchCount
});
var result = new List<string>();
while (await list.MoveNextAsync())
result.AddRange(list.Current.Cast<string>());
return string.Join(',', result);
I'm not sure why you're doing everything with BsonDocuments, you can just iterate over the data directly and return strings.
Also, consider upgrading to .NET Core 3, which you can then use C# 8's async enumerable. You'll also be able to use the new JSON functionality built-in .NET Core 3.
This will return:
"122.8.208.9,196.62.107.243,182.188.38.219,<all the rest>"

Enable sharding from C# MongoDb

I'm using Mongo 4 with the latest C# driver. My application creates DBs and Collections on the fly and I want to enable sharding. I'm using the following code:
if (!ShardingEnabled) return;
var database = collection.Database;
var databaseName = database.DatabaseNamespace.DatabaseName;
var collectionName = collection.CollectionNamespace.CollectionName;
var shardDbScript = $"{{ enableSharding: \"{databaseName}\" }}";
var shardDbResult = database.RunCommand<MongoDB.Bson.BsonDocument>(new MongoDB.Bson.BsonDocument() {
{ "eval",shardDbScript }
});
var adminDb = Client.GetDatabase("admin");
var shardScript = $"{{shardCollection: \"{databaseName}.{collectionName}\"}}";
var commandDoc = new BsonDocumentCommand<MongoDB.Bson.BsonDocument>(new MongoDB.Bson.BsonDocument() {
{ "eval",shardScript }
});
var response = adminDb.RunCommand(commandDoc);
I get an 'ok' response back from mongo, but my dbs arent sharded.
Output from sh.status()
{
"_id" : "uat_Test_0",
"primary" : "SynoviaShard2",
"partitioned" : false,
"version" : {
"uuid" : UUID("69576c3b-817c-4853-bb02-ea0a8e9813a4"),
"lastMod" : 1
}
}
How can I enable sharding from within C#?
I figured it out. This is how you shard a database and its collections from c#, note, that the sharding key index must already exist:
if (!ShardingEnabled) return;
var database = collection.Database;
var adminDb = Client.GetDatabase("admin");
var configDb = Client.GetDatabase("config");
//var dbs = Client.ListDatabaseNames().ToList();
var databaseName = database.DatabaseNamespace.DatabaseName;
var collectionName = collection.CollectionNamespace.CollectionName;
var shardDbResult = adminDb.RunCommand<MongoDB.Bson.BsonDocument>(new MongoDB.Bson.BsonDocument() {
{ "enableSharding",$"{databaseName}" }
});
var shardScript = $"{{shardCollection: \"{databaseName}.{collectionName}\"}}";
var commandDict = new Dictionary<string,object>();
commandDict.Add("shardCollection", $"{databaseName}.{collectionName}");
commandDict.Add("key",new Dictionary<string,object>(){{"_id","hashed"}});
var bsonDocument = new MongoDB.Bson.BsonDocument(commandDict);
var commandDoc = new BsonDocumentCommand<MongoDB.Bson.BsonDocument>(bsonDocument);
var response = adminDb.RunCommand(commandDoc);

Apply filter on Dimension or Metric in Google Analytics API using C# library

I have been able to authenticate my app on google analytics and display some data around unique page views. Now I want to get the page views based on Traffic source but I'm not quite sure how to get the filters on the dimensions. I have written my code in c# and can't get my head around examples in other languages I've seen. i have used the api Query Explorer and got the right expressions and results. My difficulty is how to translate that into my code. My code is below
var filepath = Server.MapPath("~/jsonfile"); // path to the json file for the Service account
GoogleCredential credentials;
using (var stream = new FileStream(filepath, FileMode.Open, FileAccess.Read))
{
string[] scopes = { AnalyticsReportingService.Scope.AnalyticsReadonly };
var googleCredential = GoogleCredential.FromStream(stream);
credentials = googleCredential.CreateScoped(scopes);
}
var reportingService = new AnalyticsReportingService(
new BaseClientService.Initializer
{
HttpClientInitializer = credentials
});
var dateRange = new DateRange
{
StartDate = "2016-10-28",
EndDate = "2016-12-20"
};
var sessions = new Metric
{
Expression = "ga:uniquePageviews",
Alias = "Sessions"
};
var social = new Dimension { Name = "ga:socialNetwork" };
var reportRequest = new ReportRequest
{
DateRanges = new List<DateRange> { dateRange },
Dimensions = new List<Dimension> { social },
Metrics = new List<Metric> { sessions },
ViewId = "myviewid"
};
var getReportsRequest = new GetReportsRequest
{
ReportRequests = new List<ReportRequest> { reportRequest }
};
var batchRequest = reportingService.Reports.BatchGet(getReportsRequest);
var response = batchRequest.Execute();
foreach (var x in response.Reports.FirstOrDefault().Data.Rows)
{
Response.Write(string.Join(", ", x.Dimensions) + " " + string.Join(", ", x.Metrics.First().Values));
}
You should create a DimensionFilterClauses and pass it to the ReportRequest as follows:
//Create the Dimension Filter
var dimensionFilter = new DimensionFilter();
dimensionFilter.DimensionName = "ga:socialNetwork";
dimensionFilter.Expressions = new List<string> { "someValue" };
var dimensionFilterClause = new DimensionFilterClause();
dimensionFilterClause.Filters = new List<DimensionFilter> { dimensionFilter };
Then modify your ReportRequest:
var reportRequest = new ReportRequest
{
DateRanges = new List<DateRange> { dateRange },
Dimensions = new List<Dimension> { social },
Metrics = new List<Metric> { sessions },
ViewId = "myviewid",
DimensionFilterClauses = new List<DimensionFilterClause> { dimensionFilterClause }
};
P.S:
Furthermore, if you need to filter Metric instead of Dimension, you would need to create a MetricFilterClauses as follows and then pass it to MetricFilterClauses in your ReportRequest:
//Create the Metric Filter
var metricFilter = new MetricFilter();
metricFilter.MetricName = "someMetric";
metricFilter.ComparisonValue = "someValue";
var metricFilterClause = new MetricFilterClause();
metricFilterClause.Filters = new List<MetricFilter> { metricFilter };

Can Update a photo tags in existing One

My question is can able to add a tag from existing one (means existing phtos).Now iam able to tag a friends in fresh upload using this code
private const string ExtendedPermissions = "user_about_me,user_photos,publish_stream";
[HttpPost]
[FacebookAuthorize(Permissions = ExtendedPermissions, LoginUrl = "/Home/LogOn?ReturnUrl=~/Home")]
public ActionResult MensagemPost(string message)
{
var fb = new FacebookWebClient();
dynamic me = fb.Get("me");
string friendId_1 = // get the first one friend id
string friendId_2 = // get the second one friend id
var tags = new[]
{
new { tag_uid = friendId_1, x = 20, y = 20 },
new { tag_uid = friendId_2, x = 40, y = 40 },
new { tag_uid = (string)me.id, x = 60, y = 60 }
};
dynamic parameters = new ExpandoObject();
parameters.message = message;
parameters.tags = tags;
parameters.url = "http://1.bp.blogspot.com/-evheT51sfeM/TlO_wZ8YDqI/AAAAAAAAA8I/fjlg0G8AgMY/s1600/The-best-top-hd-desktop-naruto-shippuden-wallpaper-naruto-shippuden-wallpapers-hd-11.jpg";
dynamic result = fb.Post("me/photos", parameters);
return RedirectToAction("Index", new { success = true });
}
but cannot i update the tags in existing one.
My try IS
var res = FbClient.Post("/4333418373210452/tags", PostInfo);
AccessToken = Properties.Settings.Default.FBAccessToken;
FacebookClient FbClient = new FacebookClient(AccessToken);
var PostInfo = new Dictionary<string, object>();
var tags = new[] { new { tag_uid = "870415313026255", tag_text = "Tag updated", x = 90, y = 110 } };
PostInfo.Add("tags", tags);
var result = FbClient.Post("/4333418373210452/tags", PostInfo);
This code is getting error from facebook.The error says
(GraphMethodException - #100) Unsupported post request. Please read
the Graph API documentation at
https://developers.facebook.com/docs/graph-api
i try to googling but cannot get the solution till now ..anyone help me out..your comments also welcome
Jagadeesh Govindaraj
Found the solution...previously i'm try to POST REQUEST Against my friend ID, But now i changed to phtoID..Its Worked.
AccessToken = Properties.Settings.Default.FBAccessToken;
FacebookClient FbClient = new FacebookClient(AccessToken);
var PostInfo = new Dictionary<string, object>();
var tags = new[] { new { tag_uid = "870415313026255", tag_text = "Tag updated", x = 90, y = 110 } };
PostInfo.Add("tags", tags);
var result = FbClient.Post("/"Existing PhotoID"/tags", PostInfo);

Why doesn't StartWorkflow() start my workflow in C#?

I am attempting to programatically start a SharePoint 2013 workflow. The workflow takes five parameters, puts them in an email body and e-mails them to me. When I go to the SharePoint website I can start this workflow manually, so I know the workflow is correct. When I try to use the SharePoint API's to start the workflow, I get no errors, I get an empty Guid back, and the workflow does not run.
public Guid Add(Project project)
{
var result = Guid.Empty;
var siteUri = new Uri(ConfigurationManager.AppSettings["SharePoint.Site"]);
var workflowName = ConfigurationManager.AppSettings["SharePoint.WorkflowName"];
using (var clientContext = TokenHelper.GetS2SClientContextWithWindowsIdentity(siteUri, null))
{
var workflowServiceManager = new WorkflowServicesManager(clientContext, clientContext.Web);
var workflowSubscriptionService = workflowServiceManager.GetWorkflowSubscriptionService();
var subscriptions = workflowSubscriptionService.EnumerateSubscriptions();
clientContext.Load(subscriptions, subs => subs.Where(sub => sub.Name == workflowName));
clientContext.ExecuteQuery();
foreach (var subscription in subscriptions)
{
var instanceService = workflowServiceManager.GetWorkflowInstanceService();
var initiationData = new Dictionary<string, object>
{
{"pProjectName", project.Name},
{"pDivision", _divisionData.GetDivisionName(project.DivisionId ?? Guid.Empty) },
{"pOperatingGroup", "****TODO: Operating Group****"},
{"pClientName", _clientData.GetClientName(project.ClientId ?? Guid.Empty) },
{"pSiteUrl", "****TODO: Site URL****" }
};
var startResult = instanceService.StartWorkflow(subscription, initiationData);
result = startResult.Value;
}
}
return result;
}
string subscriptionID = "WFListSubscriptionID of your wf";//it is a guid
int itemID = "Item.ID, Id of a item that you start wf for";
Guid workflowSubscriptionIdGuid = new Guid(subscriptionID);
var workflowServiceManager = new WorkflowServicesManager(item.Web);
var workflowSubscriptionService = workflowServiceManager.GetWorkflowSubscriptionService();
var workflowSubscription = workflowSubscriptionService.GetSubscription(workflowSubscriptionIdGuid);
var inputParameters = new Dictionary<string, object>();
workflowServiceManager.GetWorkflowInstanceService().StartWorkflowOnListItem(workflowSubscription, itemID, inputParameters);

Categories

Resources