Beware of the ControlMode of SharePoint:FormField


My client has custom forms for a list in SharePoint 2010. Display/Edit/New all have customization. Within this customization there are your common SharePoint FormField and FieldDescription tags such as:

<SharePoint:FormField runat=“server” id=“ff2{$Pos}” ControlMode=“New” FieldName=“Title” __designer:bind=“ddwrt:DataBind(‘i’,concat(‘ff2′,$Pos),’Value’,’ValueChanged’,’ID’,ddwrt:EscapeDelims(string(@ID)),’@Title’)}”/>

<SharePoint:FieldDescription runat=“server” id=“ff2description{$Pos}” FieldName=“Title” ControlMode=“New”/>

Be aware of the “ControlMode“. This will be tied to your SPBasePermissions, which I’ve tried to override using the SPTrimmedControl block–which that does not work. Using the ControlMode=”Edit” will give users an access denied when trying to view using a user that only has Read permissions. In order to view ControlMode=”Edit”, the user needs to have Contribute permissions. Therefore, if the user has only Read permissions, the ControlMode must equal Display.

The context of the problem arose when I used the Edit ControlMode in the Display Form, and using jQuery to disable the textbox for just viewing. Sometimes the textboxes of the fields just look cleaner and are easier to read.

PSConfig Configuration Failed


I had a client that I was applying a patch to and the PSConfig failed. Usually, I know that if it fails once, for good measure you are supposed to try to run the PSConfig again (always run as administrator with the install account)…..but it failed again. Okay….what’s going wrong? I looked more into the logs and it told me that the Usage and Health database was part of a mirror or availability group.

04/10/2015 09:01:33.82  OWSTIMER (0x530C)      0x3FC8  SharePoint Foundation Upgrade                SPUpgradeSession          aj0ur      ERROR  Upgrade Timer job is exiting due to exception: System.Data.SqlClient.SqlException (0x80131904): The operation cannot be performed on database “SP13_UsageAndHealth” because it is involved in a database mirroring session or an availability group. Some operations are not allowed on a database that is participating in a database mirroring session or in an availability group.  ALTER DATABASE statement failed.     at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)     at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)     at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)    

Once I removed the Usage and Health database from the availability group, and ran the PSConfig again, it succeeded.

Is this a database that really shouldn’t be in the AlwaysOn availability group? That’s odd to me. I wonder if newer patches will recognize this, and allow this database to be in the AlwaysOn availability group.

Happy SharePointing!

FIM Sync error


I had an implementation which had a FIM Sync problem that it would find all the AD objects that it needed to find, but the user profile sync wouldn’t create the profiles, which remained at 0. In the ULS logs you may see something along the lines of “Unsupported Method”, going to the UIShell of the sync service in “C:\Program Files\Microsoft Office Servers\Synchronization Service\15.0\UIShell\miisclient.exe” you may see the error “stopped-extension-dll-load“, but there is no additional information about it. In your event viewer you may find:

The management agent “MOSS-UserProfile” failed on run profile “MOSS_EXPORT_GUID”. The run step stopped because a configured extension for this management agent could not be loaded.

User Action
Verify that the extension is located in the Extensions directory. If the extension is present, confirm that the version of the .NET framework that can run the extension is installed on the server and that a supportedRuntimes entry in the configuration files specifies that version. The synchronization engine will not be able to load an extension that is built with a newer version of the .NET framework than the version of the .NET runtime it is hosting.

Turns out that this is somehow due to the supported runtime being commented out in miisserver.exe.config

<startup useLegacyV2RuntimeActivationPolicy=”true”>
<!– <supportedRuntime version=”v4.0.30319″></supportedRuntime> –>
<supportedRuntime version=”v2.0.50727″></supportedRuntime>
</startup>

Delete uncomment the line to make it look like this:

<startup useLegacyV2RuntimeActivationPolicy=”true”>
<supportedRuntime version=”v4.0.30319″></supportedRuntime>
<supportedRuntime version=”v2.0.50727″></supportedRuntime>
</startup>

Restart the server that hosts the Sync Service. You can find out by going to CA -> Manage Service Applications -> Highlight User Profile Service -> Properties

Creating New Multi-Lookup Values from Custom Forms


I was working with a client where they wanted to add a new Multi-Lookup value on the New Item form. This will be a customized new item form that will add a link to popup a new item of that multi-lookup value. SPServices has something that will add the SPLookup (http://spservices.codeplex.com/wikipage?title=$().SPServices.SPLookupAddNew&referringTitle=Documentation), but wasn’t verified for SharePoint 2013 and had caveats for 2010, so I was unsure about the solution. I read some blogs that show you how to explicitly add a new lookup value, using the following format:

|t<ID>|t<LOOKUPVALUE>|t

where <ID> = the ID of the lookup item and <LOOKUPVALUE> = the lookup value/text of the item

The tricky part to this is that there are <select> tags and <input> tags that are hidden that you need to add and remove, this will force you to reinvent the wheel of adding and removing the option from the two panel display:

 

I think I was tackling it from a different angle, so I just used the refresh and with HTML5, you have the ability to use localStorage. localStorage is used for what cookies previously was used for in the prior versions. You can write and store key/value pairs that will stay with the browser even after you close the browser out (much like a cookie). So I think it may be easier to capture the values of the form, and reinsert the values whenever the new item is added and the form is refreshed.

<script type=”text/javascript” src=”../../Style Library/js/jquery-1.11.1.min.js”></script>
<script type=”text/javascript”>
$(document).ready(function(){

$(“input[id$=’TextField’]”).filter(“input[title=’Name’]”).val(localStorage.getItem(‘name’));
$(“input[id$=’TextField’]”).filter(“input[title=’Address’]”).val(localStorage.getItem(‘address’));
$(“input[id$=’TextField’]”).filter(“input[title=’Address 2′]”).val(localStorage.getItem(‘address2′));
$(“input[id$=’TextField’]”).filter(“input[title=’City’]”).val(localStorage.getItem(‘city’));

localStorage.removeItem(‘name’);
localStorage.removeItem(‘address’);
localStorage.removeItem(‘address2’);
localStorage.removeItem(‘city’);

});

function AddNewRig()
{

OpenPopUpPage(‘/../../Lists/<List>/NewForm.aspx?IsDlg=1′,  AddItemRefresh);
}

function AddItemRefresh()

{

var name = $(“input[id$=’TextField’]”).filter(“input[title=’Name’]”).val();
var address = $(“input[id$=’TextField’]”).filter(“input[title=’Address’]”).val();
var address2 = $(“input[id$=’TextField’]”).filter(“input[title=’Address 2′]”).val();
var city = $(“input[id$=’TextField’]”).filter(“input[title=’City’]”).val();
localStorage.setItem(“name”, name );
localStorage.setItem(“address”, address);
localStorage.setItem(“address2”, address2 );
localStorage.setItem(“city”, city);
location.reload();

}

</script>

 

Basically, upon loading the form, it will look for the localstorage keys, then set the form values for each textbox/control. You then delete the keys so that it doesn’t conflict with any other applications that use it. SharePoint will handle the loading of the Multi-lookup control with the new item that the user just created, so whenever you refresh the page, the form will load the Item you just added while retaining any information that the user previously put inside the form. A new key/value pair will have to be set/get/deleted for each column or field in the form.

 

Workflows running twice


I’ve found that in some cases during a migration, workflows may have the ability to run twice. You can even start a brand new workflow for a list, and even that will run twice. I looked more into it, and it appears that upon migration, both the 14 and 15 version event receivers were present. I did some powershell to find and remove the 14 (I’m on SP2013) event receivers.

$spWeb = Get-SPWeb -Identity http://sitewebappURL

$spList = $spWeb.Lists[“List Name Here”]

$spList.EventReceivers | Format-List Id, Assembly, Type, Class

#Find the event receivers of ItemAdded and ItemUpdated for the old version (14 if you are on sp2013, 12 if you are on sp2010, so on). Make sure this output spits out the correct receiver you are trying to delete!

$spList.EventReceivers[#]

#Use the following command to delete the old version of the event receiver. Be careful not to delete the wrong one!

$spList.EventReceivers[#].Delete()

$spList.Update()

Then, try the workflow out again, and it should only run once.

Passing Current User to another web application (ASPX)


Man, it’s been awhile since I lasted did a post. There have been a lot of changes. I have a new job and am doing consultant work now. I’m diving much more into SharePoint 2013. In fact, I am taking the 70-331 exam this month, so that should be a good step up for my bag of certifications. Anywho..

I had a requirement where I needed to grab the current user and pass the username off to another web application. How I got it to work was to embed the web application in a SharePoint app which just consisted of a web application page. All you need to do is:

1. Start up Visual Studios -> New -> Project -> SharePoint Empty Project (2013)
2. Then right click the Project -> Add -> New Item -> Application Page.
3. From here, make your application page the same page that you want to embed, carrying over any supporting files.
4. Make sure from here the application page runs correctly (taking note that there is no credential passing yet)
5. Add a reference to Microsoft.SharePoint to your project.
6. Then, let’s assume your app page is called Default. You want to edit your .aspx.cs file

Add:

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;

Also add on Default.aspx.cs:

SPWeb theSite = SPControl.GetContextWeb(Context);
SPUser theUser = theSite.CurrentUser;
string strUserName = theUser.LoginName;

Now you have control over the SPContext, so you can use that to pass objects off to the web application you need it to be.

SharePoint Designer Workflow – E-mail Body String


So I was working on a SharePoint Designer workflow and it seems as though the e-mail body was not rendering or reading the text that was in the body, it was including all of the markup with it. I was trying to include the body of an email to log to the history list.

lookupbodyworkflow

When the workflow ran, the email body output looked like this:

Image

The problem here is that the Body column is allowing Rich Format. All you have to do is change the Body format back to Plain Text.
Image

Then try to use your workflow again using E-mail Body (as string). It should show up correctly now.

Follow

Get every new post delivered to your Inbox.