InfoPath Cannot find the specified path for VSTA project

If your using InfoPath 2013 and come across this error when trying to access developer tools, its because this version of VSTA copies the code to a temp folder then then works on it there.

Problem is that temp folder are exactly that… “temp” so if the folder is lost then InfoPath will complain it cant find it.

The way around this is on the developer tab on the ribbon, click ‘Language’, click remove code (dont worry it wont delete your code).

Then click on ‘Code Editor’ again and it will make a new folder for your code in Documents > InfoPath Projects. Overwrite the contents of this new folder with the contents from the original project.

Then in VSTA look at the project properties and you will see the link to the temp folder. Open that folder, overwrite the contents of that also as before.

SharePoint App Permissions

Apps for SharePoint have permissions just as users and groups do. This enables an app to have a set of permissions that are different from the permissions of the user who is executing the app. You must request, in the app manifest file, the permissions that an app needs to run. The user who adds the app must grant these requests, and the user can only grant permissions that he or she has as a user. The grant must be for all the requested permissions or none of them to simplify the management of permissions for users and developers. (The app principal always has full control rights to the app web, so it only needs to request permissions to SharePoint resources in the host web or other locations outside the app web.)

What are Host Webs and App Web

SharePoint 2013 introduces the concept of ‘host webs’ and ‘app webs’.

Apps are deployed to the App Web.

Apps are installed to the Host Web.

 

What are App Webs

In SharePoint 2010 when creating a webpart you could create and use and SharePoint components such as lists, libraries or workflows just about anywhere in the scope of where the webpart was being activated.

SharePoint 2013 adds an additional level of isolation (for security) whereby if an App is to need a SharePoint component such as list then it must contain this list within the apps own subweb – that app’s own App Web.  App Webs are usually inside the same site collection as the Host Web, except in tenant environments where they are in the App Catalog.  Apps that require their own web are reffered to as SharePoint hosted apps.

Apps that dont need access to any SharePoint objects such as lists, can exists without an App Web. e.g. those webparts which consume data from webservices etc. These are referred to as Provider Hosted Apps.

See example below where App 1 doesnt use any SharePoint component and therefore has no App Web, whereas App 2 uses lists and workflow and requires its own App Web:

post30

Also, although the app web is typically in the same site collection as the host web it will have its own isolated domain.

For example, suppose that an app, with SharePoint components beyond
just the UI elements that can be deployed to a host web, is installed on
a host website at the following URL:

https://www.contoso.com/sites/Marketing

The app for SharePoint will be deployed to a newly created website with a URL like the following:

http://app-bdf2016ea7dacb.contosoapps.com/sites/Marketing/Scheduler

Note that this URL has the following structure:

https://App_Prefix-App_ID.App_Base_Domain/Domain_Relative_URL_of_Host_Web/App_Name

  • Domain_Relative_URL_of_Host_Web is the relative URL of the parent host web, in this case sites/Marketing.
  • App_Name is the value of the Name attribute of the app element in the appmanifest.xml file.

 

Why to apps have their own web

Microsoft states two reason for requiring App Webs for Apps. Both are for security Enforcement of App permissions (see blog post) and Protecting against Cross-domain scripting attacks.

For more detailed information see the MSDN whitepaper

InfoPath form not working via ISA server – Form cannot be submitted – offline

If you get this error:

The form cannot be submitted to the Web server either because your computer is offline or because the host server is currently unavailable. If this problem persists, contact your network administrator.

you need to open the form inside the network, right click ‘view source’ and search for “g_objCurrentFormData”.

You’ll see something like:

http:\u002f\u002fmydomain.com

You need to add a link translation to:

https:\u002f\u002fmydomain.com

 

Strange…but works!

Populating InfoPath repeating section with C# programmatically and keeping formulas

There’s lots of tutorials showing how to programmatically fill in a repeating section or table in infopath using C#. However I only found one that shows how to do this without losing formulas, formatting and validation on the controls.

The process is to clone the first row in the repeating table instead of creating new ones.

Link here: http://sharepoint.orcinus-orca.eu/archives/17

Copy sharepoint list items or library files with version history and meta data

SharePoint doesnt support copying files between libraries or lists with version history out of the box. Although when “moving” files it does work.

To get around this you can either code the solution yourself with a custom workflow or much easier just use Sharegate’s Copy SharePoint Content tool: download sharegate trial here which can copy items meta data, version history and permissions. No server install needed and a very easy to use interface. Definitely recommend.

Creating and updating a SharePoint timer job in C#

  1. First of all create a new empty sharepoint project.
  2. Add a new feature.
  3. Right click on the feature and add an event receiver.
  4. Right click on the project name and add a new c# class.

Your structure should look like:

 

In my case the class file i added was called ComplianceData.cs your will obviously be different.

Creating the timer job
Modify the class you created by extending : SPJobDefinition

Next create the constructors like below for your class:

public ComplianceData()

: base()

{

}

 

 

public ComplianceData(string jobName, SPService service, SPServer server, SPJobLockType targetType)

: base(jobName, service, server, targetType)

{

}

 

 

public ComplianceData(string jobName, SPWebApplication webApplication)

: base(jobName, webApplication, null, SPJobLockType.ContentDatabase)

{

this.Title = “MiWorld Compliance Feed Refresh”;

}

 

After this create an execute method:

public override void Execute(Guid contentDbId)

{

// get a reference to the current site collection’s content database

SPWebApplication webApplication = this.Parent as SPWebApplication;

SPContentDatabase contentDb = webApplication.ContentDatabases[contentDbId];

 

//do whatever you need here

 

}

 

Activating the timer job

Next open the feature event receiver class and add the below code:

const string List_JOB_NAME = “MyTimerJob”;

 

public override void FeatureActivated(SPFeatureReceiverProperties properties)

{

SPWebApplication webApp = properties.Feature.Parent as SPWebApplication;

 

// make sure the job isn’t already registered

 

foreach (SPJobDefinition job in webApp.JobDefinitions)

{

 

if (job.Name == List_JOB_NAME)

 

job.Delete();

 

}

 

// install the job

 

ComplianceData listLoggerJob = new ComplianceData(List_JOB_NAME, webApp);

 

SPMinuteSchedule schedule = new SPMinuteSchedule();

 

schedule.BeginSecond = 0;

 

schedule.EndSecond = 59;

 

schedule.Interval = 30;

 

listLoggerJob.Schedule = schedule;

 

listLoggerJob.Update();

}

 

// Uncomment the method below to handle the event raised before a feature is deactivated.

 

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)

{

SPWebApplication webApp = properties.Feature.Parent as SPWebApplication;

 

// delete the job

 

foreach (SPJobDefinition job in webApp.JobDefinitions)

{

if (job.Name == List_JOB_NAME)

{

job.Delete();

}

}

}

 

In the code above we’re creating a new timer job once the feature is activated and settings its frequency to run every thirty minutes. You can also use SPHourlySchedule or SPDailySchedule. We also tell the timer which class to execute when the timer job runs.

The final thing to do is to set the feature scope to WebApplication.

All done.

Updating the timer job
If you decide to make changes after deploying the solution, you may find your timer job doesnt update. This is because you need to change the assembly versions in the AssemblyInfo.cs file.

Force Reinstall of SharePoint 2010 Solution through Visual Studio 2010 – Error occurred in deployment step ‘Add Solution’

If you get the following message in Visual Studio 2010 when deploying a SP2010 webpart:

Error occurred in deployment step ‘Add Solution’ – Use the force attribute to explicitly re-install the feature

Fear not theres a simple fix…. just add AlwaysForceInstall attribute to featurename.Template.xml and set it to True

Update masterpage ReplaceContent on SP2010 Masterpage and Page layouts on deploy

SharePoint 2013 offers a long awaited ability to simply use ReplaceContent=”true” inside a sharepoint module.

SharePoint 2010 doesnt have this ability. In order to achieve the same affect you need to create the following code for the feature activation:

using System;

using System.Collections.Generic;

using System.Xml.Linq;

using System.Text;

using Microsoft.SharePoint;

using Microsoft.SharePoint.Administration;

using System.Globalization;

using System.Xml;

using System.Collections;

using System.Linq;

 

namespace TestSPSolution

{

public class UpdateFiles : SPFeatureReceiver

{

public override void FeatureActivated(SPFeatureReceiverProperties properties)

{

if (properties != null)

{

using (SPSite currentSite = (SPSite)properties.Feature.Parent)

{

using (var web = currentSite.OpenWeb())

{

var ElementDefinitions = properties.Definition.GetElementDefinitions(CultureInfo.CurrentCulture);

 

foreach (SPElementDefinition ElementDefinition in ElementDefinitions)

{

if (ElementDefinition.ElementType == “Module”)

{

Helper.UpdateFilesInModule(ElementDefinition, web);

}

}

}

 

}

}

}

 

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)

{

//// throw new NotImplementedException();

}

 

public override void FeatureInstalled(SPFeatureReceiverProperties properties)

{

////throw new NotImplementedException();

}

 

public override void FeatureUninstalling(SPFeatureReceiverProperties properties)

{

//// throw new NotImplementedException();

}

}

 

internal static class Helper

{

internal static void UpdateFilesInModule(SPElementDefinition elementDefinition, SPWeb web)

{

XElement xml = elementDefinition.XmlDefinition.ToXElement();

XNamespace xmlns = “http://schemas.microsoft.com/sharepoint/”;

string featureDir = elementDefinition.FeatureDefinition.RootDirectory;

Module module = (from m in xml.DescendantsAndSelf()

select new Module

{

ProvisioningUrl = m.Attribute(“Url”).Value,

PhysicalPath = featureDir,

Files = (from f in m.Elements(xmlns.GetName(“File”))

select new Module.File

{

 

FilePath = (m.Attribute(“Path”) == null) ? string.Empty : Path.Combine(featureDir, m.Attribute(“Path”).Value),

Name = f.Attribute(“Url”).Value,

Properties = (from p in f.Elements(xmlns.GetName(“Property”))

select p).ToDictionary(

n => n.Attribute(“Name”).Value,

v => v.Attribute(“Value”).Value)

}).ToArray()

}).First();

 

if (module == null)

{

return;

}

 

foreach (Module.File file in module.Files)

{

 

string physicalPath = string.IsNullOrEmpty(file.FilePath) ? Path.Combine(module.PhysicalPath, file.Name) : Path.Combine(file.FilePath, file.Name);

string virtualPath = string.Concat(web.Url, “/”, module.ProvisioningUrl, “/”, file.Name);

 

if (File.Exists(physicalPath))

{

using (StreamReader sreader = new StreamReader(physicalPath))

{

if (!CheckOutStatus(web.GetFile(virtualPath)))

{

web.GetFile(virtualPath).CheckOut();

}

SPFile spFile = web.Files.Add(virtualPath, sreader.BaseStream, new Hashtable(file.Properties), true);

spFile.CheckIn(“Updated”, SPCheckinType.MajorCheckIn);

if (CheckContentApproval(spFile.Item))

{

spFile.Approve(“Updated”);

}

 

spFile.Update();

}

}

}

 

}

 

private static bool CheckOutStatus(SPFile file)

{

if (file.CheckOutStatus != SPFile.SPCheckOutStatus.None)

{

return true;

}

else

{

return false;

}

}

 

private static bool CheckContentApproval(SPListItem listitem)

{

bool isContentApprovalEnabled = listitem.ParentList.EnableModeration;

 

return isContentApprovalEnabled;

}

 

public static XElement ToXElement(this XmlNode node)

{

XDocument xDoc = new XDocument();

 

using (XmlWriter xmlWriter = xDoc.CreateWriter())

 

node.WriteTo(xmlWriter);

 

return xDoc.Root;

 

}

}

 

public class Module

{

public string ProvisioningUrl { get; set; }

public string PhysicalPath { get; set; }

public Module.File[] Files { get; set; }

 

public class File

{

public string FilePath { get; set; }

public string Name { get; set; }

public Dictionary<string, string> Properties { get; set; }

}

}

}