Client Object Model Sharepoint How to get the Instance ID - sharepoint

So In my sharepoint site contents page i have an application.
Can anyone tell me how to get the instance id of it.
so that i can invoke the link :
http://testingwebcompany.sharepoint.com/_layouts/15/appredirect.aspx?instance_id={ <>}
I can't seem to get it when I'm searching ClientContext.Web.Lists.
Thanks

I got it, it seems that the instance id is auto generated. the real url of the application is located when looping through ClientContext.Web.Webs[].Title == "Application Name" then retrieving the ClientContext.Web.Webs[].Url.

The following example demonstrates how to retrieve an App by its title
public static class WebExtensions
{
public static IEnumerable<AppInstance> GetAppInstanceByTitle(this Web web,string appTitle)
{
var ctx = web.Context;
var apps = AppCatalog.GetAppInstances(ctx, web);
var result = ctx.LoadQuery(apps.Where(a => a.Title == appTitle));
return result;
}
}
Usage
using (var ctx = new ClientContext(webUri))
{
var appTitle = "\"Napa\" Office 365 Development Tools";
var result = ctx.Web.GetAppInstanceByTitle(appTitle);
ctx.ExecuteQuery();
var app = result.FirstOrDefault();
if (app != null) Console.WriteLine(app.Id); // print App Instance Id
}

Related

Programmatically modify ACL to give application pool all permissions to application (IIS)

I have a process that creates an application and application pool using the Server Manager object in the Microsoft.Web.Administration namespace, the application pool is created first and then the application, assigning the newly created app pool to the application, code below.
protected TResult UseServerManagerWrapper<TResult>(Func<ServerManager, TResult> func)
{
using (var serverManager = new ServerManager())
{
return func(serverManager);
}
}
Application creation function
public void CreateApplication(String siteName, String parentApplicationName, String organisationName, String applicationName, String applicationPoolName)
{
UseServerManagerWrapper(serverManager =>
{
var site = serverManager.Sites[siteName];
var newApplication =
site.Applications.Add(
GetApplicationPath(parentApplicationName, organisationName, applicationName),
this.GetGeneratedApplicationPhysicalPath(siteName, parentApplicationName, organisationName, applicationName));
newApplication.ApplicationPoolName = applicationPoolName;
serverManager.CommitChanges();
return true;
});
}
and app pool creation.
public Boolean CreateApplicationPool(String applicationPoolName)
{
return UseServerManagerWrapper(serverManager =>
{
var appPool = serverManager.ApplicationPools.Add(applicationPoolName);
appPool.ManagedPipelineMode = ManagedPipelineMode.Integrated;
appPool.ManagedRuntimeVersion = "";
serverManager.CommitChanges();
return true;
});
}
This all works fine, the only problem I have is that I have to go into the application folder and manually assign permissions for the application pool.
I can't see anything in the ServerManager documentation that can help me and I can't figure out a way to use the Directory.SetAccessControl Method to give an application pool permissions. Is there anyway to do this in code?
Apologies if I'm using wrong terminology or anything, I'm new to publishing in general. Let me know if you need anymore info.
Ok, so after a lot of searching and some trial and error I've found the resolution and it's nothing to do with the ServerManager object. First of all to get this to work in ASP.NET Core 2.1 (1.x/2.x) I needed the System.IO.FileSystem.AccessControl Nuget and the Namespaces below.
using System.Security.AccessControl;
using System.Security.Principal;
These give the ability to modify the ACL of files and folders and then the CreateApplication function becomes the below.
public void CreateApplication(String siteName, String parentApplicationName, String organisationName, String applicationName, String applicationPoolName)
{
UseServerManagerWrapper(serverManager =>
{
var site = serverManager.Sites[siteName];
var generatedPath = this.GetGeneratedApplicationPhysicalPath(siteName, parentApplicationName, organisationName, applicationName);
var newApplication =
site.Applications.Add(
GetApplicationPath(parentApplicationName, organisationName, applicationName),
generatedPath);
newApplication.ApplicationPoolName = applicationPoolName;
var dInfo = new DirectoryInfo(generatedPath);
var acl = dInfo.GetAccessControl();
var acct = new NTAccount($"IIS APPPOOL\\{applicationPoolName}");
acl.AddAccessRule(new FileSystemAccessRule(acct, FileSystemRights.FullControl, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.NoPropagateInherit, AccessControlType.Allow));
dInfo.SetAccessControl(acl);
serverManager.CommitChanges();
return true;
});
}
The code between "newApplication.ApplicationPoolName = applicationPoolName" and "serverManager.CommitChanges()" gets the ACL from the newly generated directory giving the ability to modify it and reassign with a new FileSystemAccessRule.

Number of items to show in Javascript

I'm using Content Search Web Part on SP 2013, I'm trying to get the value for Number of items to show option in Javascript from the ctx object. I have tried ctx.ListData.ResultTables[0].RowCount but seems like this value is for the count on the current page only, not the configured in the 'Number of items to show' option within web part configuration.
Number of items to show value in UI
In addition, do you know where can I find more information on how to debug the ctx object or the properties or methods it uses. Any help would be appreciated. Thanks in advance.
We can use JSOM to achieve it. The following code for your reference.
<script type="text/javascript">
ExecuteOrDelayUntilScriptLoaded(retrieveWPProperties, "sp.js");
function retrieveWPProperties(){
var pageurl=_spPageContextInfo.serverRequestPath; //current page
var currentCtx = new SP.ClientContext.get_current();
var pageFile = currentCtx.get_web().getFileByServerRelativeUrl(pageurl);
var webPartManager = pageFile.getLimitedWebPartManager(SP.WebParts.PersonalizationScope.shared);
var webPartDefs = webPartManager.get_webParts();
currentCtx.load(webPartDefs, 'Include(WebPart.Properties)');
currentCtx.executeQueryAsync(
function () {
if (webPartDefs.get_count()) {
for (var i = 0; i < webPartDefs.get_count() ; i++) {
var webPartDef = webPartDefs.getItemAtIndex(i);
var webPart = webPartDef.get_webPart();
var properties = webPart.get_properties();
//console.log(JSON.stringify(properties.get_fieldValues())); //print all properties
if(properties.get_fieldValues().Title=="Content Search"){
var resultsPerPage=properties.get_fieldValues().ResultsPerPage;
alert(resultsPerPage);
}
}
}
else {
console.log("No web parts found.");
}
},
function (sender, args) {
console.log(args.get_message());
});
}
</script>

Update Modified field in Office 365

Is there any way to update the Modified field in Office 365? I have checked both CSOM and Batch update methods. But it's failed. Could anybody help me to update this field.
Before attempting to set Modified, Created, Editor, and Author fields for a list item you need to disable a couple of properties on the List, specifically EnableVersioning and for good measure ForceCheckout.
SharePoint Online prerequisite is the SharePointOnline CSOM:
.NET client API reference for SharePoint Online
Nuget - Microsoft.SharePointOnline.CSOM
using (var context = new ClientContext(webUrl))
{
context.Credentials = new SharePointOnlineCredentials(userName,password);
var list = context.Web.Lists.GetByTitle(listTitle);
var item = list.GetItemById(itemID);
var user = context.Web.EnsureUser(accountName);
context.Load(user);
context.Load(list);
context.Load(item);
context.ExecuteQuery();
// If the properties are enabled on the list then disable them
bool updateList = list.ForceCheckout || list.EnableVersioning;
if (list.ForceCheckout) list.ForceCheckout = false;
if (list.EnableVersioning) list.EnableVersioning = false;
if (updateList)
{
list.Update();
context.ExecuteQuery();
}
// Now set the fields that are normally locked
item["Modified"] = DateTime.Now;
item["Created"] = DateTime.Now.AddDays(-3);
item["Author"] = user.Id;
item["Editor"] = user.Id;
item.Update();
context.ExecuteQuery();
}
SharePoint CSOM API does not support system update (SystemUpdate method counterpart from SSOM API) but you could manipulate system fields like Modified By and Modified fields directly as demonstrated below.
Prerequisites: SharePoint Server 2013 Client Components SDK
using (var ctx = GetContext(webUri, userName, password))
{
//get List Item
var list = ctx.Web.Lists.GetByTitle(listTitle);
var item = list.GetItemById(itemId);
//Retrieve User
var user = ctx.Web.EnsureUser(accountName);
ctx.Load(user);
ctx.ExecuteQuery();
//Update system fields
item["Modified"] = DateTime.Now.AddMonths(-6);
item["Created"] = DateTime.Now.AddYears(-1);
item["Editor"] = user.Id;
item["Author"] = user.Id;
item.Update();
ctx.ExecuteQuery();
}
where
public static ClientContext GetContext(Uri webUri, string userName, string password)
{
var securePassword = new SecureString();
foreach (var ch in password) securePassword.AppendChar(ch);
return new ClientContext(webUri) { Credentials = new SharePointOnlineCredentials(userName, securePassword) };
}
SharePoint CSOM API now support system update using UpdateOverwriteVersion method. This way you can modify Modified, Created, Author and Editor properties without changing the item Version. For example:
$file = Get-PnPFile -Url $FileUrl -AsListItem
##update file properties
$item["Modified"] = $FileModifiedDate
$item["Created"] = $FileCreatedDate
$item["Author"] = $FileCreatedByDest.ID
$item["Editor"] = $FileModifiedByDest.ID
$fileTest2.UpdateOverwriteVersion()
Invoke-PnPQuery
That should do the trick.

Get membership provider Name

I am using Asp.net memebership provider for FBA in sharePoint 2013. Please let me know how to dynamically find membership provider name.
Thanks in advance.
Thanks for the response.
My scenario is I am dynamically planning to get membership provider as I have to create token during forms authentication.
I found the answer
private static string GetFbaZoneUrl(SPWeb web)
{
string providerAndRole = null;
SPWebApplication webApp = web.Site.WebApplication;
foreach (var zone in webApp.IisSettings.Keys)
{
var settings = webApp.IisSettings[zone];
var fbaProvider = webApp.IisSettings[zone].FormsClaimsAuthenticationProvider;
if (fbaProvider != null)
{
// We found the zone on the web app where FBA is enabled.
// This is the zone whose URL we want.
// SPAlternateUrl fbaUrl = webApp.AlternateUrls.GetResponseUrl(zone, false);
providerAndRole = fbaProvider.MembershipProvider + "," + fbaProvider.RoleProvider;
break;
}
}
return providerAndRole;
}
Hope this code helps someone.
Thanks
Rama
This is quite easy , in CSOM get the current username (if you are logged in with a forms based account) .The username will be of the following format :
"i:0#.f|membership|someone.example.com"
The "i:0#.f|membership|someone.example.com" is the membership provider name. Use javascript substring function to get this section.
To get the current user loginname, use the following code which is also provided here
function GetCurrentUsername()
{
var ctxt = new SP.ClientContext.get_current();
this.website = ctxt.get_web();
this.currentUser = website.get_currentUser();
ctxt.load(currentUser);
ctxt.executeQueryAsync(Function.createDelegate(this, this.onSucceess), Function.createDelegate(this, this.onFail));
}
function onSucceess(sender, args)
{
alert(currentUser.get_loginName());
}
function onFail(sender, args)
{
alert('request failed ' + args.get_message() + '\n'+ args.get_stackTrace());
}

Replacement for DoesUserHavePermissions for List object in SP2013

I'm working on an app that reuses some code from a previous solution.
The idea is to show a user all of the lists of a certain type in all the webs in a site collection so that the user can aggregate some data.
static public List<SPListMeta> AllSiteAnnouncementsLists(ClientContext clientContext)
{
var returnList = new List<SPListMeta>();
var per = new BasePermissions();
per.Set(PermissionKind.Open);
if (clientContext.Site.RootWeb.DoesUserHavePermissions(per).Value)
{
var rootWebLists = clientContext.Site.RootWeb.Lists;
returnList.AddRange(from List oList in rootWebLists
where oList.DoesUserHavePermissions(SPBasePermissions.ViewListItems) &&
where oList.BaseTemplate == (int)ListTemplateType.Announcements
select new SPListMeta(oList));
var collWebs =
clientContext.Site.OpenWebById(clientContext.Site.RootWeb.Id).GetSubwebsForCurrentUser(null);
foreach(Web oWeb in collWebs)
{
}
}
return returnList;
}
The critical line that does not work and does not seem to have a replacement is
oList.DoesUserHavePermissions(SPBasePermissions.ViewListItems)
as this has been removed from the CSOM List object
What's the new way to do this?
The new way to check for permissions is:
List.EffectiveBasePermissions.Has(PermissionKind.Open)

Resources