Impersonation for SharePoint 2010 LINQ to DataContext

Impersonation in SharePoint is not really the hardest to do. However the C# code snippet below was sort of new for me. In order to obtain impersonation for a DataContext, that was something.

Impersonation for the ClientContext … but the LINQ DataContext is constructed in another way… and by default using the current user… regardless the user you’ve set in SPContext.

So… here it is.

 

strUrl = SPContext.Current.Web.Url;

HttpContext backupContext = HttpContext.Current;
try
{
  
SPUserToken userToken = null;
  userToken =
SPContext.Current.Web.AllUsers[“SHAREPOINT\\system”].UserToken;

  // if there is a SPContext make it is as null so LINQ won’t execute under current context
  
if (SPContext.Current != null)   HttpContext.Current = null;

  SPSecurity.RunWithElevatedPrivileges(delegate() {
    using (SPSite oSite = newSPSite(strUrl, userToken)) {
      using (SPWeb oWeb = oSite.OpenWeb()) {
                               // creating a new HttpContext under elevated permission and
             // setting it as current control context web,
             // because of this the code will be running under elevated permission.

        HttpRequest httpRequest = newHttpRequest(“”, oWeb.Url, “”);
        HttpContext.Current = newHttpContext(httpRequest, new HttpResponse(new System.IO.StringWriter()));
        
SPControl.SetContextWeb(HttpContext.Current, oWeb);

        using (SomeDataContext dc = SomeDataContext(oWeb.Url)) 
        
{
          var comments = from c in dc.SomeDataContext
                         where c.Var1 == someVariable 
                        
select c;
                    }
      }
    }
  });

}

catch (Exception ex) {}
finally {
   // make sure that you are setting the actual SPContext back
   //
after your operation and make SharePoint happy J

   if (SPContext.Current != nullHttpContext.Current = backupContext;
}

Advertisement

Search SharePoint 2010 Managed Metadata Terms with an Ampersand

Already struggling with the poor functionality of the web service interface of the Taxonomy web service of SharePoint 2010, I stumbled upon another challenge.

I was building a MS CRM 2011 Plugin that populates the SharePoint Term Store using the Taxonomy web service (http://<sharepointurl>/_vti_bin/TaxonomyClientService.asmx).
The first problem was the poor functionality of the web service like being unable to add Labels to Terms.
This cannot be fixed worked around.

Then I had to query SharePoint for a Term that contained an ampersand.
Adding the Term was not a problem when the XML was escaped properly.

string _newterm = “V&D”;

_newterm = _newterm.Replace(“&”, “&amp;”).Replace(“<“, “&lt;”).Replace(“>”, “&gt;”).Replace(“\””, “&quot;”).Replace(“‘”, “&apos;”);

 

But when the SharePoint is queried for a certain Term… it works slightly different.

The TermStore can be queried for example using “GetTermsByLable()”

 

string TermXml = SPTaxService.GetTermsByLabel(TermLabel,

1033,


StringMatchOption.ExactMatch,

10,

NewTermXml,


false);

 

When you send use the TaxonomyClientService.asmx, the service will not find your term, even though when you created it you used the exact same string.

The reason is that an & will be stored by SharePoint as \uFF06

So when you wanna search for a Term, make sure you replace the ampersand… like…

 

string XmlTerm = “<newTerms><newTerm label=\”” + _newterm.Replace(“&”, “\uFF06”) + “\” clientId=\”1\” parentTermId=\”” + Guid.Empty + “\”></newTerm></newTerms>”);

 

The weird thing is, that the VS2010 Debugger still will show you the &amp;
The result from SharePoint is the right one…

So …replacing the & with &amp; does not work..!

Disclose MS CRM Online 2011 data in SharePoint 2010 Online

Thanks to LightningTools following blog post, I was able to quickly disclose CRM Online data is SharePoint Online.
Check out this post.

http://www.lightningtools.com/blog/archive/2012/02/20/crm-2011-online-and-sharepoint-2010-integration-through-business-connectivity.aspx

I am working myself working on the post of connecting to SharePoint 2010 Online from MS CRM 2010 Workflow or Plugin Assembly. The workflow assembly is not supported in MS CRM 2011 Online just yet… but the beta of RU8 is released. The wait is for the RU for MS CRM 2011 Online.

Check out my blog… I will post the solution shortly.

Localized ASP.NET RangeValidator with correct DateFormat

I needed a RangeValidator for some date-fields on my ASP.NET pages.
The pages are localized and translated… so the date-formats need to change accordingly.

All was well… until I added a minimum and maximum value for the RangeValidator… something like 1-1-1900 and 1-1-2100.
I got a really cool error:

The value ‘1-1-1901’ of the MaximumValue property of ‘rangevalidatorStartDate’ cannot be converted to type ‘Date’.

 

So I figured… I need to localize the Min and Max date-string:
So I added this in the code behind.

 

rangevalidatorStartDate.MinimumValue = DateTime.MinValue.AddYears(1900).ToShortDateString();

 

The error was not fixed yet… because… you need to localize the parsing of the date according to Culture of the page.
Then the code looks like this.

protected
void Page_Load(object sender, EventArgs e)

{

IFormatProvider culture = new
CultureInfo(Session[“MyCulture”].ToString(), true);

 

string minDate = DateTime.Parse(DateTime.MinValue.AddYears(1900).ToShortDateString(), culture).ToShortDateString();

string maxDate = DateTime.Parse(DateTime.MinValue.AddYears(2100).ToShortDateString(), culture).ToShortDateString();

 

rangevalidatorStartDate.MinimumValue = minDate;

rangevalidatorStartDate.MaximumValue = maxDate;

}

 

 

Then the markup looks like this.

 

<td><asp:TextBox
ID=”txtStartDate” runat=”server”
/>


<asp:RequiredFieldValidator

ID=”StartdateFieldValidator” runat=”server”

        ControlToValidate=”txtStartDate”

        ForeColor=”red”


ErrorMessage=””


Text=”*”

        Display=”Dynamic”

        CssClass=”validation-message” Width=”7px”
/>


<asp:RangeValidator


runat=”server”


ID=”rangevalidatorStartDate”


Type=”Date”


ControlToValidate=”txtStartDate”


ErrorMessage=”<%$Resources:eService,entityeditor_invaliddatemessage%>


Display=”None”
/>

</td>

How to make MS CRM 2011 ADX Studio Customer Portal MultiLingual

I had some issues making the ADX Studio Customer Portal multilingual.
First I tried having a duplicate website with duplicatie site markers and all… this was way too much.

I solved it just a little easier… use as much translations from CRM as possible… since there are a whole load of translations available when you install a language pack.
In this article I use Dutch and English.

First let me show you the markup for a page with a grid view displaying CRM data.

asp:GridView
ID=”GridView1″ runat=”server” CssClass=”cases” AutoGenerateColumns=”False”
>


<Columns>

    <asp:TemplateField
HeaderText=”Study”>

        <HeaderTemplate >

            <asp:Literal
ID=”ltrHeader1″ runat=”server” Text=’<%# GetHeaderText(“cbr_study”) %>‘></asp:Literal>

        </HeaderTemplate>

        <ItemTemplate>

        <asp:HyperLink
ID=”hlUrl” runat=”server” NavigateUrl=’<%# EducationUrl( (Guid)Eval(“cbr_educationid”) ) %>

Text=’<%# Eval(“cbr_study”)%>
/>

        </ItemTemplate>

    </asp:TemplateField>

    <asp:TemplateField
HeaderText=”Institution”>

        <HeaderTemplate >

            <asp:Literal
ID=”ltrHeader2″ runat=”server” Text=’<%# GetHeaderText(“cbr_institutionid”) %>‘></asp:Literal>

        </HeaderTemplate>

        <ItemTemplate>

            <%#
ContentUtility.FormatCrmEntityReference(Eval(“cbr_institutionid”) as
CrmEntityReference) %>

            <%# Eval(“cbr_institute_not_listed”)%>

        </ItemTemplate>

    </asp:TemplateField>

    <asp:TemplateField
HeaderText=”Start Date”>

        <HeaderTemplate >

            <asp:Literal
ID=”ltrHeader3″ runat=”server” Text=’<%# GetHeaderText(“cbr_startdate”) %>‘></asp:Literal>

        </HeaderTemplate>

        <ItemTemplate>

            <%# GetLocalDate(Eval(“cbr_startdate”) as
DateTime?) %>

        </ItemTemplate>

    </asp:TemplateField>

    <asp:TemplateField
HeaderText=”End Date”>

        <HeaderTemplate >

            <asp:Literal
ID=”ltrHeader4″ runat=”server” Text=’<%# GetHeaderText(“cbr_graduationdate”) %>‘></asp:Literal>

        </HeaderTemplate>

        <ItemTemplate>

            <%# GetLocalDate(Eval(“cbr_graduationdate”) as
DateTime?)%>

        </ItemTemplate>

    </asp:TemplateField>

    </Columns>

</asp:GridView>

 

In the code behind of this page, you´ll need the method GetHeaderText… taking the CRM field name as only argument..

In the Session-object I stored MyLanguageCode… holding the 1033 or 1043… whatever the user picked as display language.

 

protected
string GetHeaderText(string crmField)

{

return
ContentUtility.GetLocalizedLabel(XrmContext, crmField, “cbr_education”, (int)Session[“MyLanguageCode”]);

}

 

I add in the ContentUtility class a two methods … GetLocalizedLabel and GetLocalizedPickListValues

 

public
static
string GetLocalizedLabel(XrmServiceContext context, string crmField, string crmEntity, int LanguageCode)

{


RetrieveAttributeRequest CrmAttributeRequest = new
RetrieveAttributeRequest();

CrmAttributeRequest.EntityLogicalName = crmEntity;

CrmAttributeRequest.LogicalName = crmField;

 


RetrieveAttributeResponse response = (RetrieveAttributeResponse)context.Execute(CrmAttributeRequest);

 


if (response.AttributeMetadata.DisplayName.LocalizedLabels.Where(l => l.LanguageCode == LanguageCode).Any() == true)

{


return response.AttributeMetadata.DisplayName.LocalizedLabels.Where(l => l.LanguageCode == LanguageCode).SingleOrDefault().Label;

}

 


// Otherwise return the default label


return response.AttributeMetadata.DisplayName.LocalizedLabels.Single().Label;

}

 

public
static
ListItemCollection GetLocalizedPickListValue(XrmServiceContext context, string crmField, string crmEntity, int LanguageCode)

{


RetrieveAttributeRequest CrmAttributeRequest = new
RetrieveAttributeRequest();

CrmAttributeRequest.EntityLogicalName = crmEntity;

CrmAttributeRequest.LogicalName = crmField;

 


RetrieveAttributeResponse response = (RetrieveAttributeResponse)context.Execute(CrmAttributeRequest);


PicklistAttributeMetadata picklist = (PicklistAttributeMetadata)response.AttributeMetadata;

 


ListItemCollection ddItems = new
ListItemCollection();


string _localizedlabel = string.Empty;

 


foreach (OptionMetadata option in picklist.OptionSet.Options)

{


if (option.Label.LocalizedLabels.Where(l => l.LanguageCode == LanguageCode).Any() == true)

{

_localizedlabel = option.Label.LocalizedLabels.Where(l => l.LanguageCode == LanguageCode).SingleOrDefault().Label;

}


else

{

_localizedlabel = option.Label.LocalizedLabels.Single().Label;

}

 

ddItems.Add(new
ListItem(_localizedlabel, option.Value.ToString()));

}


return ddItems;

}


 

JQuery Mobile Web Client on SharePoint – The Source Code

After numerous requests of publishing the source code of my demo as showed before in JQuery Mobile Web Client on SharePoint enabled I have decided to do so.
You lucky bastards… from the goodness of my hart… and for the good of community… and for world peace.

Please be aware that the solution has not left the alpha stage.
Download the code here … SharePoint4Mobile… this is a .DOC file, cause WP didn’t allow me to upload an archive.
So …  rename the download from .DOC to .ZIP and you’ll be all set.

Things you wanna know:

  • It was developed against SharePoint 2007 in an BPOS environemnt… so you come across some BPOS specific tag in the ASPX  pages.
  • It is mainly JavaScript, cause of the BPOS SharePoint 2007 restrictions… you can make this work using .NET better and faster I’ll bet.
  • An important component I used was the 2008 SPAPI by Darren Johnstone (http://darrenjohnstone.net).

Good luck and feel free to let me know what the experiences were with this piece of code.
I’m allways open for feedback.

 

You may wonder why I stopped developing futher.
This has a fairly simple reason.

My goal was developing an App that enabled a user on at least iPhone or iPad to not just Open and Edit MS Office files… but Save modified files back to SharePoint.
This last feature … saving changed files back to SharePoint – is not possible with iPhone or iPad.
Read one of many articles stating what Apple had NOT done to to leverage SharePoint functionality with an iPhone or iPad.
http://blog.wortell.nl/jasper/the-ipad-and-sharepoint-%E2%80%93-what-can-and-can%E2%80%99t-you-do-%E2%80%93-part-1/

 

Pass a ListItemId to SharePoint workflow

In SharePoint Designer 2007 open the page where an action is needed.

Right click the control the wher you want to start the workflow from… click Form Actions.

Add Custom Action and click Settings and the Workflow Wizard will start.

Click Variables and add a variable called something like MyListItemId.

Finish the workflow and see that the code around your control will be updated somewhat like this:

<a href=”javascript: {ddwrt:GenFireServerEvent(‘__workflowStart={{FA532C23-6F80-4266-868D-1EBC219A7E11},New,{8F0B8599-4B45-421A-A4A2-9BD2817078DE},}’)}”>
//MyControl//
</a>

 

Here’s what you need to do to pass the variable MyListItemId

<a href=”javascript: {ddwrt:GenFireServerEvent(concat(‘__workflowStart={{FA532C23-6F80-4266-868D-1EBC219A7E11},New,{8F0B8599-4B45-421A-A4A2-9BD2817078DE},MyListItemId=’,@ID, ‘}’))}”>
//MyControl//
</a>

 

EASY AS PIE

The length of the ‘filteringattributes’ attribute of the ‘sdkmessageprocessingstep’ entity exceeded the maximum allowed length of ‘100’

 

While developing a plug-in for CRM 4.0 triggers can be set when the plug-in can be set off using the Plugin Registration Tool.

When too many triggers are selected the following error will occur.

Unhandled Exception: System.Web.Services.Protocols.SoapException: Server was unable to process request.
Detail:

A validation error occurred. The length of the ‘filteringattributes’ attribute of the ‘sdkmessageprocessingstep’ entity exceeded the maximum allowed length of ‘100′.
Platform

at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
at PluginRegistrationTool.CrmSdk.CrmService.Create(BusinessEntity entity)
at PluginRegistrationTool.RegistrationHelper.RegisterStep(CrmOrganization org, CrmPluginStep step)
at PluginRegistrationTool.StepRegistrationForm.btnRegister_Click(Object sender, EventArgs e)

 

What is de filteringattribute attribute?

While registering a plugin trigger in the CRM database the [<OrganizatioName>_MSCRM].[SdkMessageProcessingStepBase] table is updated.
For every plugin step a record is created in this table.
One of the attributes in this table is

[FilteringAttributes] [nvarchar](256)
NULL

During the registration of the plugin step the MetadataSchema is checked and validated a.o. the MaxLength of this attribute.

SELECT Maxlength
FROM [<OrganizationName>_MSCRM].[MetadataSchema.Attribute]
wHERE name =’filteringattributes’

By default the result of this query will be ‘100’. Strange of course since the database will allow to insert nvarchar strings up to 256 characters.

A solution could be

Update [<OrganizationName>_MSCRM].[MetadataSchema.Attribute
SET Maxlength = 256
where name =’filteringattributes’

If the MaxLength is set to more then 256 a SQL Error may occur since data will be truncated.

Note: After an update IISReset /noforce is required.

Note: Above customization is unsupported and you must take precautionary measure to make sure to avoid any problem with CRM system.