Microsoft Land

Archive for May 2011

When using Enhanced rich text box in SharePoint 2010 / 2007, it doesn’t give the users the ability to insert EMBED / OBJECT tags into the content.  Even if inserted, these tags will be removed once the item is saved.  One of the important feature that users want is to embed the OBJECT tag (YouTube Video for example) while they are creating a Blog Post.

Found couple of Good Articles which i liked and are handy.  Below are the links.

AS2J3H3RET8X

http://blogs.msdn.com/b/kaevans/archive/2010/06/15/embedding-flash-video-in-sharepoint-blogs.aspx

http://blogs.msdn.com/b/sharepointdesigner/archive/2009/12/11/video-blogging-with-javascript-and-the-media-web-part.aspx

Please read the Part 1 of this blog entry to understand the Background if needed.

Ok Let’s create a Empty SharePoint Project in Visual Studio 2010 (SharePoint2010.Controls).

Add Mapped SharePoint folders (Right click on solution)

1) Control Templates

2) XML (Template/XML)

Add a new Class for our FileUploadCustomField (FileUploadCustomField.cs -> Namespace SharePoint2010.Controls.FileUploadCustomField).  Below is the code for this class.  We will use a Custom Property i.e., UploadDocumentLibrary to save the name of the document library to where the documents / images have to be uploaded (Selected from the drop down when creating the column).  Inherit this class from Microsoft.SharePoint.SPTextField.

 public FileUploadCustomField(SPFieldCollection fields, string fieldName) : base(fields, fieldName) { Init(); }
public FileUploadCustomField(SPFieldCollection fields, string typeName, string displayName) : base(fields, typeName, displayName) { Init(); }

private string _UploadDocumentLibrary = string.Empty;
public string UploadDocumentLibrary
{
get
{
return _UploadDocumentLibrary;
}
set
{
this.SetCustomProperty(“UploadDocumentLibrary”, value);
_UploadDocumentLibrary = value;
}
}

private void Init()
{
this.UploadDocumentLibrary = this.GetCustomProperty(“UploadDocumentLibrary”) + string.Empty;
}

public override void Update()
{
this.SetCustomProperty(“UploadDocumentLibrary”, this.UploadDocumentLibrary);
base.Update();
}

public override BaseFieldControl FieldRenderingControl
{
get
{
BaseFieldControl fieldControl = new FileUploadCustomFieldControl();
fieldControl.FieldName = InternalName;
return fieldControl;
}
}

Now let’s create the class FieldUploadCustomFieldControl under the same namespace as above. This will have to be Inherited from Microsoft.Sharepoint.WebControls.BaseFieldControl.  Below is the code for this class.

protected FileUpload UploadFileControl;
protected Button UploadButton;
protected Label StatusLabel;
protected HiddenField hdnFileName;

public override void Focus()
{
if (Field == null || this.ControlMode == SPControlMode.Display)
{ return; }
EnsureChildControls();
UploadFileControl.Focus();
}
public override object Value
{
get
{
EnsureChildControls();
if (hdnFileName.Value!=string.Empty)
return hdnFileName.Value;
else if (UploadFileControl.PostedFile != null)
{
string strFileName = UploadFileControl.PostedFile.FileName.Substring(UploadFileControl.PostedFile.FileName.LastIndexOf(“\\”) + 1);
return strFileName;
}
else
{
return null;
}
}
set
{
EnsureChildControls();
hdnFileName.Value = (string)this.ItemFieldValue;
StatusLabel.Text = “File: <a href='” + (string)this.ItemFieldValue + “‘ target=’_blank’>View (” + (string)this.ItemFieldValue + “)</a>”;
}
}

protected override void CreateChildControls()
{
if (Field == null || this.ControlMode == SPControlMode.Display)
{ return; }

base.CreateChildControls();

UploadFileControl = (FileUpload)TemplateContainer.FindControl(“UploadFileControl”);
UploadButton = (Button)TemplateContainer.FindControl(“UploadButton”);
StatusLabel = (Label)TemplateContainer.FindControl(“StatusLabel”);
hdnFileName = (HiddenField)TemplateContainer.FindControl(“hdnFileName”);

UploadButton.Click += new EventHandler(UploadButton_Click);

if (hdnFileName.Value==string.Empty)
StatusLabel.Text = “Select file and click on upload.”;
else
StatusLabel.Text = “File: <a href='” + hdnFileName.ToString() + “‘ target=’_blank’>View (” + hdnFileName.ToString() + “)</a>”;
Controls.Add(StatusLabel);
}

protected void UploadButton_Click(object sender, EventArgs e)
{
SPWeb sourceWeb;

SPSite sourceSite = SPControl.GetContextSite(Context);
sourceWeb = sourceSite.AllWebs["/"];
sourceWeb.AllowUnsafeUpdates = true;
FileUploadCustomField _field = (FileUploadCustomField)this.Field;
SPList objList = sourceWeb.Lists[_field.UploadDocumentLibrary];
SPFolder destFolder = objList.RootFolder;
try
{
if (UploadFileControl.PostedFile == null) return;
string strFileName = UploadFileControl.PostedFile.FileName.Substring(UploadFileControl.PostedFile.FileName.LastIndexOf(“\\”) + 1);

Stream fStream = UploadFileControl.PostedFile.InputStream;

SPFile objFile = destFolder.Files.Add(strFileName, fStream, true);
objFile.Item.UpdateOverwriteVersion();

StatusLabel.Text = “Upload File :: Success <a href='” + “/” + objFile.ParentFolder + “/” + strFileName + “‘ target=’_blank’>View (” + “/” + objFile.ParentFolder + “/” + strFileName + “)</a>”;
hdnFileName.Value = “/” + objFile.ParentFolder + “/”  + strFileName;
sourceWeb.Dispose();
}
catch (Exception ex)
{
StatusLabel.Text = “Upload File :: Failed ” + ex.Message;
}

}

protected override string DefaultTemplateName
{
get
{
return “FileUploadControlTemplate”;
}
}

Now, see the DefaultTemplateName property that we are overriding.  We are returning “FileUploadControlTemplate” as the Template name.  Let’s create this template (an ASCX file that needs to go under Control templates folder – An user control).  Delete the .CS files for this as we don’t need them.

<%@ Assembly Name=”$SharePoint.Project.AssemblyFullName$” %>
<%@ Assembly Name=”Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c” %>
<%@ Register Tagprefix=”SharePoint” Namespace=”Microsoft.SharePoint.WebControls” Assembly=”Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c” %>
<%@ Register Tagprefix=”Utilities” Namespace=”Microsoft.SharePoint.Utilities” Assembly=”Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c” %>
<%@ Register Tagprefix=”asp” Namespace=”System.Web.UI” Assembly=”System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″ %>
<%@ Import Namespace=”Microsoft.SharePoint” %>
<%@ Register Tagprefix=”WebPartPages” Namespace=”Microsoft.SharePoint.WebPartPages” Assembly=”Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c” %>
<%@ Control Language=”C#” %>

<SharePoint:RenderingTemplate ID=”FileUploadControlTemplate” runat=”server”>
<Template>
<asp:FileUpload ID=”UploadFileControl” runat=”server” CssClass=”ms-ButtonHeightWidth” Width=”250px” />
<asp:Button ID=”UploadButton” runat=”server” CssClass=”ms-ButtonHeightWidth” Width=”50px” CausesValidation=”false” Text=”Upload”/>
<asp:Label ID=”StatusLabel” runat=”server” Width=”300px” />
<asp:HiddenField ID=”hdnFileName” runat=”server” />
</Template>
</SharePoint:RenderingTemplate>

Now we have Field and Field Control ready.  We also need to create an Editor control which will display the Drop down while creating the Column to show the Target document library into which the file has to be uploaded (We are using that in the Field Control above). Add a User Control to the solution (FileUploadFieldEditControl.ASCX).  Now move the .ASCX to the control templates folder and leave the .CS files under the solution as we want to Package them and Push the ASCX to the Control Templates folder.

ASCX File will be

<%@ Assembly Name=”$SharePoint.Project.AssemblyFullName$” %>
<%@ Assembly Name=”Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c” %>
<%@ Register TagPrefix=”SharePoint” Namespace=”Microsoft.SharePoint.WebControls”
Assembly=”Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c” %>
<%@ Register TagPrefix=”Utilities” Namespace=”Microsoft.SharePoint.Utilities” Assembly=”Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c” %>
<%@ Register TagPrefix=”asp” Namespace=”System.Web.UI” Assembly=”System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″ %>
<%@ Import Namespace=”Microsoft.SharePoint” %>
<%@ Register TagPrefix=”WebPartPages” Namespace=”Microsoft.SharePoint.WebPartPages”
Assembly=”Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c” %>
<%@ Control Language=”C#” AutoEventWireup=”true” Inherits=”SharePoint2010.Controls.FileUploadFieldEditControl” %>
<%@ Register TagPrefix=”wssuc” TagName=”InputFormControl” Src=”~/_controltemplates/InputFormControl.ascx” %>
<%@ Register TagPrefix=”wssuc” TagName=”InputFormSection” Src=”~/_controltemplates/InputFormSection.ascx” %>
<wssuc:InputFormSection runat=”server” id=”UploadControl” Title=”Upload Control Configuration Section”>
<template_inputformcontrols>
<wssuc:InputFormControl runat=”server” LabelText=”Select document library”>
<Template_Control>
<asp:DropDownList ID=”ddlDocLibs” runat=”server” CssClass=”ms-ButtonheightWidth” Width=”250px” />
</Template_Control>
</wssuc:InputFormControl>
</template_inputformcontrols>
</wssuc:InputFormSection>

Declare the Drop Down Control in the Designer CS file.

protected DropDownList ddlDocLibs;

Add the Logic in the User Control Code behind file to populate the drop down with Document Libraries.  This class has to inherit from System.Web.UI.UserControl and the Interface Microsoft.SharePoint.WebControls.IFieldEditor.

FileUploadCustomField _field = null;

public bool DisplayAsNewSection
{
get { return true; }
}

public void InitializeWithField(SPField field)
{
this._field = field as FileUploadCustomField;
}

public void OnSaveChange(SPField field, bool isNewField)
{
FileUploadCustomField myField = field as FileUploadCustomField;
myField.UploadDocumentLibrary = ddlDocLibs.SelectedItem.Text;
}

protected override void CreateChildControls()
{
base.CreateChildControls();
SPListCollection objLists = SPContext.Current.Web.Lists;
foreach (SPList objList in objLists)
{
if (objList is SPDocumentLibrary)
ddlDocLibs.Items.Add(new ListItem(objList.Title, objList.Title));
}
if (!IsPostBack && _field != null)
{
if (!String.IsNullOrEmpty(_field.UploadDocumentLibrary))
FindControlRecursive<DropDownList>(this, “ddlDocLibs”).Items.FindByText(_field.UploadDocumentLibrary).Selected = true;
}
}

protected T FindControlRecursive<T>(Control rootControl, String id)
where T : Control
{
T retVal = null;
if (rootControl.HasControls())
{
foreach (Control c in rootControl.Controls)
{
if (c.ID == id) return (T)c;
retVal = FindControlRecursive<T>(c, id);
if (retVal != null) break;
}
}
return retVal;
}

Now, we have come to last step of building this control and deploying it.  Create an XML file under the XML folder and name it “FLDTYPES_FileUploadCustomField.xml”.

<?xml version=”1.0″ encoding=”utf-8″ ?>
<FieldTypes>
<FieldType>
<Field Name=”TypeName”>FileUploadCustomField</Field>
<Field Name=”TypeDisplayName”>File Upload Custom Field</Field>
<Field Name=”TypeShortDescription”>File Upload Custom Field</Field>
<Field Name=”ParentType”>Text</Field>
<Field Name=”UserCreatable”>TRUE</Field>
<Field Name=”ShowInListCreate”>TRUE</Field>
<Field Name=”ShowInSurveyCreate”>TRUE</Field>
<Field Name=”ShowInDocumentLibraryCreate”>TRUE</Field>
<Field Name=”ShowInColumnTemplateCreate”>TRUE</Field>
<Field Name=”FieldTypeClass”>SharePoint2010.Controls.FileUploadCustomField, $SharePoint.Project.AssemblyFullName$</Field>
<Field Name=”FieldEditorUserControl”>/_controltemplates/FileUploadFieldEditControl.ascx</Field>
<PropertySchema>
<Fields>
<Field Name=”UploadDocumentLibrary” DisplayName=”Select target Document Library” Type=”Text” Hidden=”True”/>
</Fields>
</PropertySchema>
</FieldType>
</FieldTypes>

And build and deploy the solution.

We are working on a Intranet Portal which needs to have a list with few columns along with images/documents.  So business users when adding items to the List in the sharepoint site, there and then they want to upload an Image / PDF / Document which needs to be associated with that List item.  We have a custom webpart which renders the list information along with the image in a particular based on the business need.

Initially thought to add a site column of type Enhanced rich text but this causes issues as Enhanced rich text automatically inserts DIV tags sorrounding the image tag which is hard to capture and render within the webpart by removing the DIV tags and any additional inline styling.  Moreover it doesn’t make sense to ask the business users to just insert that document link / image in a rich text.

I am going to explain this in two different blog posts – Part 1 – Outline the need / design, Part 2 – Code – Howtos

So we have decided to create a new site field which will allow business users to upload the document using a simple file upload control.

So that when Business users are adding a new item to the list they really have to upload a file as they wanted to as shown below.  This also allows us to control the location where the files will be saved so that we can track them / setup retention policies as needed.

SharePoint allows us to create our own Site fields which will help us to extend the OOB delivered site fields and build out own logic to organize the content that business users want to save to the Site.

So all that we need to build and talk about are 4 things.

  1. File Upload Site Field (This is what is the actual field that we select when we are creating the new column)
  2. File Upload Site Field Control (This is the control that needs to be displayed when users are adding / editing a list item)
  3. File Upload Site Field Edit Control (This is the Drop down from which we select the target document library while creating a new site column)
  4. File Upload Site Field Configuration XML (The field type configuration that SharePoint users to know / identify / render the field)

Let’s navigate to Part 2 of this blog entry to see how we build this. (I am using Visual Studio 2010 / SharePoint 2010).

Came across a funny issue today.  We have a custom webpart which is using Update Panel to do it’s job.  When the post back is happening, it just removes the page title of the Site and keeps it blank.  Looked at various areas which are possibly causing this issue and ended up in the master page where below snippet is there.

<title id=”onetidTitle”>

<asp:ContentPlaceHolder ID=”PlaceHolderPageTitle” runat=”server” />

</title>
Just tried to play with it.  Changed it to

<title id=”onetidTitle”><asp:ContentPlaceHolder ID=”PlaceHolderPageTitle” runat=”server” /></title>

And that solved the problem.  It’s the spaces in the tag which are causing the issue.

This blog entry is to walkthrough how to Use OpenSSL to setup a new Certificate Authority & to issue a Certificate from that Certificate Authority to Sign an Infopath Form. I tried best to keep it simple, hope it helps.

Step 1: Download Open SSL installer for Windows http://www.slproweb.com/products/Win32OpenSSL.html.

Once you have installed, Open SSL will have a default Certificate Authority Configured into it (Mostly with the name of demoCA).

Now add the Bin directory of the OpenSSL Installation folder in to the path.

Step 2: Let’s setup our own Certificate Authority. Every certificate authority need to have a Certificate Authority Root folder along with a folder structure / default files that it uses in conjunction with OpenSSL.

  • Create the below Folder structure (I am assuming that it’s created under C:\ Drive for this article).  Create a dummy text file with the name “index.txt” under “OpenSSLCA” (Open Notead, do not type anything save it with the filename index.txt under the folder OpenSSLCA).  “index.txt” will act as a the database for OpenSSL to store Certificates information.

   Folder “certreq” -> Meant to store all the certificate requests that came long to this certificate authority, Folder “certs” -> Will store all the certificates,  Folder “crl” -> will store the certificate revocation list, Folder “newcerts” is where OpenSSL puts the created certificates in PEM format – OpenSSL needs this so we will have to create it, Folder “private” -> Will store all the private keys.

  • Open command prompt and navigate to “OpenSSLCA” folder (Start -> Run -> CMD (enter key) -> CD c:\OpenSSLCA)
  • Insert the command (echo 01 > serial) and press enter, this creates the file serial under “OpenSSLCA” folder.
  • Copy the default OpenSSL Configuration file into our Root CA folder.  (Start -> Run -> CMD (enter key) – CD C:\OpenSSLCA\CARoot (enter key) copy <<OpenSSL Installation Root>>\bin\OpenSSL.cfg MyCompany.cfg
  • Let me give a brief description of how our file extension naming convensions are going to be
    • KEY – Private key (Restrictive permissions should be set on this)
    • CSR – Certificate Request (This will be signed by our CA in order to create the server certificates. Afterwards it is not needed and can be deleted)
    • CRT – Certificate (This can be publicly distributed)
    • PEM – We will use this extension for files that contain both the Key and the server Certificate (Some servers need this). Permissions should be restrictive on these files.
    • CRL – Certificate Revokation List (This can be publicly distributed)

Step 3: Lets generate a Root Authority Certificate for CA. Navigate to the Root CA folder (c:\OpenSSLCA\CARoot).

enter the below statement.

OpenSSL req -config MyCompany.cfg -new -x509 -keyout private/MyCompany.key -out certs/MyCompany.crt -days 365

Enter the Password for the Root Certificate Authority Private Key along with other informtion regarding the Certificate authority.

Now OpenSSL generates a certificate and a private key for the Certificate authority.

Step 4: Now our CA is ready.  Let’s change the CA configuration file to point it to the right folders / certificates.

Open MyCompany.cfg that we have copied in step 2 in notepad / wordpad. Navigate to line 35 (Roughly) where you should be able to see “CA_default” section of the configuration file. The following configuration entires needs to be changed to the values as below.

dir = .

certificate = $dir/certs/MyCompany.crt

private_key=$dir/private/MyCompany.key

Save the file.

Step 5: Now our CA is ready to issue certificates for the Certificate requests.

Let’s assume that we are creating an application using Infopath / MOSS 2010 for a company “DingDong” and we want to issue the certificate to “DingDongIT” which will be used to Sign the Infopath form.

First step is to generate a Certificate request.  Second step generate the certificate.  Third step generate the certificate with a private key in .P12 format (As Infopath Needs the certificate to be in .P12 format).

Generate certificate request:

Navigate to the CA Root folder in Command line (C:\OpenSSLCA\CARoot)

OpenSSL req -config MyCompany.cfg -new -keyout private/DingDongIT.key -out certreq/DingDongIT.csr -days 365

Insert the password for the private key along with the company information of “DingDong”

OpenSSL will now generate a Certificate request for DingDongIT and places it in “certreq” folder.

Generate Certificate: (use the request to generate the certificate)

OpenSSL ca -config MyCompany.cfg -policy policy_anything -out certs/DingDingITCertificate.crt -infiles certreq/DingDongIT.csr

This generates the Private Key / certificate for DingDongIT.

Generate Certificate with a Private Key in .p12 Format:

OpenSSL pkcs12 -export -in certs/DingDongCertificate.crt -out certs/DingDongITCertificate.p12 -inkey private/DingdongIT.key -certfile certs/MyCompany.crt

This will merge the RootCA certificate and DingDongIT Certificate into a .p12 file and places it in “certs” folder.

Now our certificate is ready to be used in Infopath.  Give the certificate to DingDongIT along with the password.

Step 7: Now DingDongIT will have to install the certificate.  Double click on .P12 file and follow the wizard steps to let it install the certificate.

Open Microsoft Management Console (Start -> Run -> MMC (enter key))

In the menu select File -> Add/Remove Snapins and select the Certificates option and select “My User Account” in the popup.  This opens the certificate store for the current logged in user.  If you expand the tree view “Personal” -> “Certificates” you should be able to see the Certificate that you have just installed.

Now Open the Infopath form in Design view.  Goto Form Options -> Security and Trust and check the checkbox which says “Sign this form template”.  Click on the button “Select Certificate” you should be able to see the certificate which you just installed that was issued by the Newly created Certificate Authority.

————

Came through this Article which is good and quick way for developers to Setup the Digitally Signed Certificates for Infopath Development.

http://www.stumbleupon.com/su/1mHfRj/www.infopathdev.com/blogs/mel_balsamo/archive/2011/07/11/how-to-create-a-digital-certificate-and-publish-a-signed-template-to-the-dbxl-admin-tool.aspx

Have you ever faced this error on a MOSS 2010 website.  Here is a scenario that I came across.

We are launching a Public facing website which is built on top of MOSS 2010.  When we are testing the site in QA environment enabling the Anonymous access on the Extended Web App, we started getting this error when we are accessing the lists using Client Object Model.

So basically this an error that we normally get when there is an Anonymous site which has Client Object Model used which is accessing the lists on the site.

Fix,

http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.administration.spclientcallablesettings.aspx

Open SharePoint 2010 Management Shell (Or Open Power Shell and Load MOSS Modules)

Insert command Get-ExecutionPolicy (This will show the current Execution Policy – Make a note of it).

$webapp = Get-SPWebApplication “<<your web URL which is having the issue>>”

$webapp.ClientCallableSettings.AnonymousRestrictedTypes.Remove([microsoft.sharepoint.splist], “GetItems”)

$webapp.Update()

Now that you have changed the settings, revert back the Execution Policy to what ever it was earlier.

Set-ExecutionPolicy <<What ever it was earlier>>

Hope this will help.

Here is another intresting error that i have encountered recently.  We are working on a Custom application which is meant to do Client Budgeting in PeopleSoft Finance using Infopath 2010 Forms Services / SharePoint 2010.  As part of the Deployment Cycle / Testing Cycle we are pushing the application from DEV -> TEST -> QA -> Prod.  All the instances are different for both PeopleSoft side of it and for also the SharePoint Farm.

When we are pushing it to QA i have found this error thrown by .NET / When trying to consume a Web Service exposed from PeopleSoft Integration Broker.

  • The content type text/plain; charset=UTF-8 of the response message does not match the content type of the binding (text/xml; charset=utf-8)

Looking at it it’s evident that PeopleSoft is not sending XML’ and instead sending some text. Getting the detailed error message from PeopleSoft Response has below Information.

  • <IBInfo><Status><StatusCode>20</StatusCode><MsgSet>158</MsgSet><MsgID>10409</MsgID><DefaultTitle>Integration Gateway Error</DefaultTitle></Status></IBInfo>

Now we went back to error logs (<<PSHOME>>\FINQA\webserv\peoplesoft_FINQA\applications\peoplesoft\PSIGW) generated @ PeopleSoft side to see what actually the problem is, we found below issue logged

  •  Message content is not a MimeMesage

Fix – while going through the entire Service Configuration @ PeopleSoft end, we have figured out the Service Configuration in PeopleSoft is configured wrong.  The Target Location in Service Configuration should be <<ServiceHostMachine>>/PSIGW/PeopleSoftServiceListeningConnector, because of the WSDL exported is having invalid EndPoint URL which is causing the issue.

I am not saying that this is the reason for this, but this could be one of the reason for this error.  But overall,  closely checking the complete IB Configuration (Integration broker Quick Configuration / Service Configuration / Nodes) will help in resolving this issue.


My Tweets

Follow

Get every new post delivered to your Inbox.

Join 121 other followers