Showing posts with label SharePoint 2010. Show all posts
Showing posts with label SharePoint 2010. Show all posts

Monday, April 7, 2014

Assign default value to person field in out of the box list forms

Boy its been more than a year since I last posted. But here's the latest on my learnings...

Have you ever had a need where you are asked if you can default a person field with current logged in user? I am sure a lot of you may have, and many have went the route of InfoPath forms / 3rd party components & many may have written custom JavaScript to achieve it.

I went ahead and wrote a custom jQuery plugin that i plan to use it for this requirement moving forward. Here's the link to the plugin. In order to get it to work do the following

  1. Open your default new item form in edit mode. 
  2. Add a content editor webpart 
  3. Add content using HTML Markup by click on the content editor web part & clicking on the below options
  4.  on the HTML markup editor  add the below mentioned script
<script src="{relativesiteurl}/scripts/framework/jquery-1.10.2.min.js" type="text/javascript"></script><script src="{relativesiteurl}/scripts/framework/jQuery.commonFunctions.js" type="text/javascript"></script>


<script type="text/javascript">

$(document).ready(function () {


$().assignDefaultUserToPeoplePicker({fieldDisplayName: "Submitted by", loginName:"{loginname}"});

});

</script>

Here the
  • {relativesiteurl} is the relative path to your site collection.
  • scripts is a document library where the jQuery plugin and my custom plugin has been uploaded
  • framework is the folder inside the scripts document library that houses the js files
  • {loginname} is the network user name.

If you don't want it to default to a specific user name and would like to default to current logged in user's loginname do the  following

$().assignDefaultUserToPeoplePicker({fieldDisplayName: "Submitted by"});

I have tested the code in both SP2010 and SP2013 and it works as expected. If any of you run into issues feel free to comment here and I will get back to you as soon as i can.

SP 2010 Test - Screenshot

SP 2013 Test - Screenshot

The way this plugin works is by searching the display name that is being passed to the plugin, and assigning the people picker div the login name that is either passed to the plugin or retrieved using client side object model. It would then invoke the checknames action manually to ensure the login name assigned resolved properly and the assignment is seamless to users.

Wednesday, July 11, 2012

SharePoint TermSet and Maximum number of items that can be serialized or deserialized in an object graph is '65536'

We have a business requirement that allows the end users to read certain news articles about the company and like them and based on that it increases the like count and also tags the page with a default SharePoint "I like it" tag. This allows the page to come in the activity feed of the end users allowing his / her colleagues to see the news articles that was liked by him / her.

Everything worked fine until one fine day the custom code started breaking and the error that was getting logged in the ULS logs was

Maximum number of items that can be serialized or deserialized in an object graph is '65536' 


We found that the problem is with the default WCF service limits, as the error indicates it can only serialize 65536 objects. Ok, I understand that but why does the code fail and why is it that if I use SharePoint's native functionality "Like It" works just fine? The answer lied in the custom code that was written to trigger of "I Like it".

The line of code that was the culprit of this error was
Term term = taxSession.DefaultKeywordsTermStore.KeywordsTermSet.Terms["I like it"];

Now you will think ok, that looks perfectly fine but why did it raise the error? The reason is in how SharePoint works, as you can see above the code is actually retrieving the term by indexing on the KeywordTermSet collection. The problem with this approach is that server side code will first bring in the entire collection and then index it and retrieve the actual term. This will work fine if your Managed Metadata Store was present in the same SharePoint farm, but if you have a seperate Shared Service Farm which is hosting your Managed Metadata Store and your code lies in a seperate farm then you will definitely see the issue mentioned above.

To overcome the issue the code was changed to

TermCollection termCollection = taxSession.DefaultKeywordsTermStore.KeywordsTermSet.GetTerms("I like it", true);
Term term = termCollection[0];


This uses the built in function call to only retrieve the term and not the entire collection.

Feel free to comment or raise any questions that you may have and I will more than happy to answer them.

Thanks

Monday, July 2, 2012

Event ID: 8311 The root of the certificate chain is not a trusted root authority

So one of our customer's SharePoint portal goes live. Everyone is happy and there are celebrations all around until an error crops up in production environment which had never occurred in any of the 3 environments (developer, integration, QA).

One of the core functionality of the SharePoint Portal; a custom webpart which places an order for certain product is failing inconsistently. The point of failure was the line of code which was submitting an order on the 3rd party web service consumed by our webpart. The stack trace was as follows

System.Net.WebException: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure. at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception) at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult) at System.Threading.ExecutionContext.runTryCode(Object userData) at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result) at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size) at System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size) at System.Net.ConnectStream.WriteHeaders(Boolean async) --- End of inner exception stack trace --- at System.Web.Services.Protocols.WebClientProtocol.GetWebResponse(WebRequest request) at System.Web.Services.Protocols.HttpWebClientProtocol.GetWebResponse(WebRequest request) at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters) 

After further diving through the event logs and SharePoint ULS  logs we narrowed down to the actual problem as logged in the ULS logs and also in event logs below.





An operation failed because the following certificate has validation errors:\n\nSubject Name: CN={}, OU={}, OU={}, OU={}, O={}\nIssuer Name: CN={} OU={}, O={}, C=US\nThumbprint: {}\n\nErrors:\n\n The root of the certificate chain is not a trusted root authority


Note: I have removed the details of the actual certificate in the above stack trace

This made me to do some research and stumbling upon quite a few blogs; the most interesting one as below 
http://jeroenvanree.wordpress.com/2012/01/16/event-id-8311-the-root-of-the-certificate-chain-is-not-a-trusted-root-authority/

The above blog did explain the issue & the resolution. Which we did follow but the errors were still coming. It was only after further analysis that I realized that the 3rd party webservice consumed by the webpart has a chain of certificates assigned like screenshot on the right. 


While reading Jeroen's blog above I interpret that I need to only upload the Primary root cert and we are taken care of but it is also required for us to upload the entire chain excluding the first one in the chain (in this case webservice cert). 

Once the intermediate cert was uploaded in the Manage Trust store of SharePoint everything worked as a charm with no run time exceptions and nothing logged in Event / ULS logs. 


I decided to write a post on this to make everyone aware that don't just upload the primary root but you will need to upload all the cert in the chain excluding the first one. 


P.S. This would have been very obvious error and easy analysis if all my environments consistently threw System.Net.WebException. I am still to figure out why only certain web front ends are throwing the error while other execute the code without returning run time error but log in the Event Logs.



Monday, September 26, 2011

Display author's photo on a blog site

Ever come across a scenario where you are asked whether can you display photograph of the person who created the blog?

I was and immediately I started my research in analyzing how best to achieve this? My initial gut feel was to modify the XSLT for the blogs but as always I was trying to search if there was an OOB way to do it.

Below are the steps that you need to perform in order for this to work in OOB manner


Step 1: go to blog site

Step 2: go to Posts list

Step 3: List Settings\





















Step 4: Click on "Created By" column, and as you can see from the image above, change the Show field from Name with presence to name with picture. 
and Voila!!! it will be done. 
Something that I forgot to mention is that this will need user's photo to be uploaded on their My Profile. The users can upload their photo using their My Site. 
Hope this is helpful :) 

Friday, September 9, 2011

SharePoint 2010 and Granular security using Active Directory Groups

Recently in one of our document center portal we had a very specific requirement of providing the security to the document based on the region it was applicable. Example: A contract ABC is applicable to North America - USA & Latin America - Mexico. In this situation the document should only be visible to people who belong to those specific country.

Knowing SharePoint there is no OOB way to do it, we could have used audiences but then it requires a identifier attribute in Active Directory which will be used for identifying region and secondly audiences only limit in what is visible / presented to the end user. By that what I mean is that if the document was just presented using Audience Targetting then the document wouldn't have been visible; but if someone knows the URL of document then they could very well be able to view the document.

The solution that we ended up taking is to use workflows for identifying the region to which document belongs (by looking at a mandatory metadata column) and based on that we would assign Active Directory group for the region. The solution works in theory but the question now was how to model the AD groups?

AD groups can be created in 3 different ways but for it to work with SharePoint; it should only be created as Domain Global Security Group or Domain Universal Security Group. Domain Local just doesn't work. Because we had 2 different forests to take care of we ended up creating regional group for each forest.
One for forest ABC and other for DEF.

I wanted to create a blog for the solution as it may help someone with similar needs, please don't hesitate to contact me if any further details are required about the solution. Lastly would like to credit Joel Oleson's blog 
 that helped in designing my solution.