File Upload Custom Site Field Control – SharePoint 2010 – Part 2
Posted on: May 18, 2011
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.
37 Responses to "File Upload Custom Site Field Control – SharePoint 2010 – Part 2"
Do you happen to have the solution available for download? I’m unsure as to where the first Custom Properties are to be created.
Hi Sriram. Any idea what could cause the above or when you uploading the solution? Your help is really appreciated.
Hi Sriram,
Have you been able to spot my mistake at all?
Chris.
Hi Chris
I know this is a slightly old thread, but i would like to use this custom field in a project, but i am getting syntax errors? It seems you are the only one who managed to get it to work? Can you send me your working project please??
Don’t worry … Cracked it. Had the wrong assembly and namespace specified for my solution.
hi chris wsp file can we have it?
Hi Sriram, I want to upload documents to specific folder in document library and if folder is not available provide option to create folder and then add documnet..any idea how to do this?
It is really a nice and useful piece of information. I am happy that you shared this helpful info with us. Please stay us informed like this. Thanks for sharing.
Hi Sriram,
How do I make the fldtypes_*.xsl for this. This is if I want to show the image thumbnail in the list view
Hey Sriram,
I want to use your control inside a webpart, but I can’t get it working. I’m have the FileUploadCustomField and I’m accessing the FieldRenderingControl property of it, but if I add this control to the Controls collection, nothing seems to happen.
Hi
can u share the solution as we are facing some issues it like
TYPE SYSTEM.WEB.UI.USECONTROL DOES NOT HAVE A PUBLIC PROPERTY NAMED ‘TEMPLATE_INPUTFROMCONTROLS’
THANKS IN ADVANCE
Hi bhargavi,
You will need to reference the System.Web in your Visual Studio before importing into the code.
regards,
Kodle
can you please post the download link for the sorcecode
Hi, how can I display it in a List this custom field as hyperlink to the file, actually I have now only as path “Library/filename” like, I think I schould do something in xsl file, right?
Do you have the vb code for the above? It would be much appreciated.
Nice post. But when i create a new fileUpload custom field i got an error “Earlier versions of client programs might not support this type of column. Adding this column might block those programs from saving documents to this library.”
Hi Sriram, I would like to link FileName to File Url, I schould do it in xsl but I have now Idee how, could you please help me?
Hi Looking good blog
i am able to develop custom field type as file upload control i am able to configure the location of document library but i am getting exception like List” ” deos not existing in url http://sp-dev-12:6241 when i trying to click the upload button after browse can any one tell what i need to do
i got an error Unable to cast object of type ‘ASP._controltemplates_fileuploadfieldeditcontrol_ascx’ to type ‘Microsoft.SharePoint.WebControls.IFieldEditor’ whenever i’ve tried to add the column which i’ve created based on your steps above
would you guide me to solve it
so the issue was that i forget to inherit from “IFieldEditor”
sorry
Hi Sriram,
I think your code are missing some lines, for example, in the “FileUploadCustomField.cs”, on the ‘FieldRenderingControl’, your new FileUploadCustomField() doesn’t input the arguments as required by the 2 constructors that you have included in this example.
Or point me out if I’m wrong here.
Regards,
Kodle
Hi Sriram.
I have to hand it to you, this is a very good solution! Is there any chance you could upload the actual project its self?
Would really appreciate it.
Thanks.
I’m getting syntax errors and would just like to compare my project with a working version.
1 | File Upload Custom Site Field Control – Part 1 « Microsoft Land
May 18, 2011 at 5:22 pm
[...] I am going to explain this in two different blog posts - Part 1 – Outline the need / design, Part 2 – Code – Howtos [...]
August 28, 2012 at 1:25 am
can you please post the download link for the sourcecode