Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Saturday, August 17, 2013

Update User Profile picture programmatically in SharePoint

User Profile Service application maintains all the Information about the User available in SharePoint as User Profiles. These Information will be synchronized with the external source such as Active Directory or Custom DB by User Profile Synchronization Service running in the SharePoint server. User Profile Photo is one of the property in User Profile called “PictureUrl”. All the User Profile Photos are maintained in SharePoint library in My Site called “User Photos”, for each User Profile 3 files are maintained with various dimensions (Large,Medium and Small size) in the library.

When a User uploads a profile picture in SharePoint, these three files will be created from the chosen file and uploaded to the Profile Pictures folder in “User Photos” library under My site and the reference to the Image will be updated to the “PictureUrl” property in the User Profile.
If we are giving an option to change the Profile picture in out custom component, we also need to create these 3 different files and update the reference in User Profile property. Below code snippet will do the need.
#region Profile Image Updation
/// 
/// Updates the current User profile Image
/// 
/// 
/// 
protected void btnProfileUpload_Click(object sender, EventArgs e)
{
    try
    {
        //Uncomment if Change profile photo functionality is required
        if (Page.IsValid && ctrlUpload.HasFile)
        {
            UploadPhoto(SPContext.Current.Web.CurrentUser.LoginName, ctrlUpload.FileBytes);
        }
    }
    catch (Exception ex)
    {
        ErrorHandling.WriteLog("btnProfileUpload_Click " + ex.Message, ex, SPContext.Current.Web);
    }
}

public void UploadPhoto(string accountName, byte[] image) 
{
    SPSecurity.RunWithElevatedPrivileges(delegate()
    {
        using (SPSite site = new SPSite(webURL))
        {
            using (SPWeb web = site.OpenWeb())
            {
                web.AllowUnsafeUpdates = true;
                ProfileImagePicker profileImagePicker = new ProfileImagePicker();
                InitializeProfileImagePicker(profileImagePicker, web);
                SPFolder subfolderForPictures = GetSubfolderForPictures(profileImagePicker);
                string fileNameWithoutExtension = GetFileNameFromAccountName(accountName);
                int largeThumbnailSize = 120; int mediumThumbnailSize = 90; int smallThumbnailSize = 30;
                using (MemoryStream stream = new MemoryStream(image))
                {
                    using (Bitmap bitmap = new Bitmap(stream, true))
                    {
                        CreateThumbnail(bitmap, largeThumbnailSize, largeThumbnailSize, subfolderForPictures, fileNameWithoutExtension + "_LThumb.jpg");
                        CreateThumbnail(bitmap, mediumThumbnailSize, mediumThumbnailSize, subfolderForPictures, fileNameWithoutExtension + "_MThumb.jpg");
                        CreateThumbnail(bitmap, smallThumbnailSize, smallThumbnailSize, subfolderForPictures, fileNameWithoutExtension + "_SThumb.jpg");
                    }
                }
                SetPictureUrl(accountName, subfolderForPictures, fileNameWithoutExtension);
                web.AllowUnsafeUpdates = false;
            }
        }               
    });
}

public void SetPictureUrl(string accountName, SPFolder subfolderForPictures, string fileNameWithoutExtension)
{

    SPSite site = subfolderForPictures.ParentWeb.Site;
    UserProfileManager userProfileManager = new UserProfileManager(SPServiceContext.GetContext(site));
    UserProfile userProfile = userProfileManager.GetUserProfile(accountName);
    string pictureUrl = String.Format("{0}/{1}/{2}_MThumb.jpg", site.Url, subfolderForPictures.Url, fileNameWithoutExtension);
    userProfile["PictureUrl"].Value = pictureUrl;
    userProfile.Commit();
} 


public string GetFileNameFromAccountName(string accountName) 
{ 
    string result = accountName; 
    string charsToReplace = @"\/:*?""<>|"; Array.ForEach(charsToReplace.ToCharArray(), charToReplace => result = result.Replace(charToReplace, '_')); 
    return result; 
}   

public void InitializeProfileImagePicker(ProfileImagePicker profileImagePicker, SPWeb web) 
{ 
    Type profileImagePickerType = typeof(ProfileImagePicker); 
    FieldInfo fieldInfo = profileImagePickerType.GetField("m_objWeb", BindingFlags.NonPublic | BindingFlags.Instance); 
    fieldInfo.SetValue(profileImagePicker, web); 
    MethodInfo miLoadPictureLibraryInternal = profileImagePickerType.GetMethod("LoadPictureLibraryInternal", BindingFlags.NonPublic | BindingFlags.Instance); 
    if (miLoadPictureLibraryInternal != null) 
    { 
        miLoadPictureLibraryInternal.Invoke(profileImagePicker, new object[] { }); 
    } 
}   

public SPFile CreateThumbnail(Bitmap original, int idealWidth, int idealHeight, SPFolder folder, string fileName) 
{ 
    SPFile file = null; Assembly userProfilesAssembly = Assembly.Load("Microsoft.Office.Server.UserProfiles, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"); 
    Type userProfilePhotosType = userProfilesAssembly.GetType("Microsoft.Office.Server.UserProfiles.UserProfilePhotos"); 
    MethodInfo miCreateThumbnail = userProfilePhotosType.GetMethod("CreateThumbnail", BindingFlags.NonPublic | BindingFlags.Static);             
    if (miCreateThumbnail != null) 
    { 
        file = (SPFile)miCreateThumbnail.Invoke(null, new object[] { original, idealWidth, idealHeight, folder, fileName }); 
    } 
    return file; 
}   

public SPFolder GetSubfolderForPictures(ProfileImagePicker profileImagePicker) 
{ 
    SPFolder folder = null; 
    Type profileImagePickerType = typeof(ProfileImagePicker); 
    MethodInfo miGetSubfolderForPictures = profileImagePickerType.GetMethod("GetSubfolderForPictures", BindingFlags.NonPublic | BindingFlags.Instance); 
    if (miGetSubfolderForPictures != null) 
    {
        folder = (SPFolder)miGetSubfolderForPictures.Invoke(profileImagePicker, new object[] {true }); 
    } 
    return folder; 
}
#endregion


 

Send Calendar Meeting request in C#

To send Calendar meeting request through code first we need to format string in the form of iCalendar Outlook event. Then we have create a AlternateView object of Calendar MIME type with the formatted string. Now if we add this object to the Mail message, user will receive email in the format of Outlook Event.

Framing the String in iCalendar format and Sending Email
StringBuilder sw = new StringBuilder();        
sw.AppendLine("BEGIN:VCALENDAR");
sw.AppendLine("VERSION:2.0");
sw.AppendLine("METHOD:PUBLISH");
sw.AppendLine("BEGIN:VEVENT");
sw.AppendLine("CLASS:PUBLIC");
sw.AppendLine(string.Format("CREATED:{0:yyyyMMddTHHmmss}", DateTime.UtcNow));
sw.AppendLine("DESCRIPTION: " + desc);
sw.AppendLine(string.Format("DTEND:{0:yyyyMMddTHHmmss}", eventendDT));
sw.AppendLine(string.Format("DTSTART:{0:yyyyMMddTHHmmss}", eventstartDT));
sw.AppendLine(string.Format("ORGANIZER:MAILTO:{0}", SPContext.Current.Web.CurrentUser.Email));
sw.AppendLine("SEQUENCE:0");
sw.AppendLine("UID:" + Guid.NewGuid().ToString());
if (lblIntLocation != null && lblIntLocation.Text != "")
    sw.AppendLine("LOCATION:" + lblIntLocation.Text);
if (lblCandidateName != null && lblCandidateName.Text != "")
    sw.AppendLine("SUMMARY;LANGUAGE=en-us: Scheduled for " + lblCandidateName.Text);
else
    sw.AppendLine("SUMMARY;LANGUAGE=en-us: Scheduled");

sw.AppendLine("BEGIN:VALARM");
sw.AppendLine("TRIGGER:-PT15M");
sw.AppendLine("ACTION:DISPLAY");
sw.AppendLine("DESCRIPTION:Reminder");
sw.AppendLine("END:VALARM");
sw.AppendLine("END:VEVENT");
sw.AppendLine("END:VCALENDAR");   

string from = SPContext.Current.Web.Site.WebApplication.OutboundMailSenderAddress;

string smtpAddress = SPContext.Current.Web.Site.WebApplication.OutboundMailServiceInstance.Server.Address;

// Assign SMTP address 
SmtpClient smtpClient = new SmtpClient();
smtpClient.Host = smtpAddress;

MailMessage mailMessage = new MailMessage(from, toRecipients);
mailMessage.Subject = subject;

// Create the Alternate view object with Calendar MIME type
System.Net.Mime.ContentType ct = new System.Net.Mime.ContentType("text/calendar");
ct.Parameters.Add("method", "REQUEST");

//Provide the framed string here
AlternateView avCal = AlternateView.CreateAlternateViewFromString(sw.ToString(), ct);
mailMessage.AlternateViews.Add(avCal);

smtpClient.Send(mailMessage);
Check this article to create downloadable iCalendar files in C#

Send Email with Embedded Images in C#

You might came across a scenario where we need to add Images as part of Email sent through code in HTML format. We can directly give the absolute url of the image and add the image reference in the email. But the when the server in which the Image is hosted goes Offline, we can’t get the image in our Email. To avoid this issue we can embed the Image in Email itself and then it will be available to the User even if the server is offline.

To Embed the Image in our Email we need to create an object for LinkedResource with our image path. Later this LinkedResource will be added to AlternateView of HTML type.
Each Image references should have one unique ID associated with the Image. So first while framing the HTML we will create the Unique ID and mention in “img src” as below,
<img src=”cid:YOUR UNIQUE ID”/>
Then you need use the same unique ID (which is mentioned in Image reference) for creating the Linked Resource object.
LinkedResource obj = new LinkedResource(“Physical path of the image”, "image/png");
Obj.ContentId = “YOUR UNIQUE ID; 
 
If your Image is hosted in any site and doesn’t exists in physical folder, you can get Stream from the Image and pass the Stream as Input while creating object for LinkedResource.

 
byte[] imgByte = null;
using (var webClient = new WebClient())
{
   webClient.UseDefaultCredentials = true;
   Uri uri = new Uri(url);
   imgByte = webClient.DownloadData(uri);
}
Stream memStream = new MemoryStream(img.ImgStream);
LinkedResource pic6 = new LinkedResource(memStream, "image/png");
pic6.ContentId = img.ImgGuid.ToString();
 

Once the LinkedResource object is created we need to add to an object of AlternateView of HTL type. Below is the full sample code snippet for embedding images (Check inline comments for more details).
 
// Creating Unique ID for adding image referrence
string GUId1 = Guid.NewGuid().ToString();               
 
// frame the HTML with the img tag and above unique id
string htmlBody = "<html><body><div><img src=\"cid:" + GUId1 + "\"></div></body></html>";
 
// Create alternateview object with Mime type HTML
AlternateView avHtml = AlternateView.CreateAlternateViewFromString
                    (htmlBody, null, MediaTypeNames.Text.Html);
 
//Create object for Linked Resource with the Image physical path or Image Stream
LinkedResource pic1 = new LinkedResource(HttpContext.Current.Server.MapPath("/_layouts/Images/header.jpg"), "image/png");
 
// Provide the previously created Unique ID to associate the Image with the respective img src.
pic1.ContentId = GUId1;
 
//Add the Linked Resource to the AlternateView
avHtml.LinkedResources.Add(pic1);
 
string from = SPContext.Current.Web.Site.WebApplication.OutboundMailSenderAddress;
 
string smtpAddress = SPContext.Current.Web.Site.WebApplication.OutboundMailServiceInstance.Server.Address;
 
// Assign SMTP address
SmtpClient smtpClient = new SmtpClient();
smtpClient.Host = smtpAddress;
 
MailMessage mailMessage = new MailMessage(from, toRecipients);
mailMessage.Subject = subject;
 
// Add the Alternate view with the Mail message
mailMessage.AlternateViews.Add(avHtml);
mailMessage.IsBodyHtml = true;
 
smtpClient.Send(mailMessage);
 
 

Happy Coding!

Calling a method in Parent page from User Control

User Controls in ASP.net is a reusable server control independent of Containing parent aspx page. When a User control embedded into a Aspx Page or other control, parent control will have access to the public properties, methods and objects of the child user control. There might be a scenario where, we need to call one of the method from Parent page or Parent control from the Child User control.

So to call the method in the Parent page or control we can create one Event Handler to our User control and add the Event Handler definition in parent control. Now from the User control we can trigger that Event which will then execute the Event Handler definition in Parent control,  then from there we can call the respective method in Parent Control.
1.       Add an Event to your User Control.

public event EventHandler CreateClick;

2.       Trigger the event from the User Control whenever required on particular action.

CreateClick(sender, e); 

Below is the Code behind of the User Control
 
  //Event Handler Declaration
 public event EventHandler CreateClick;
 
  //Triggering the Event in User control
 public void CallParentEvent(object sender, EventArgs e)
 {
    if (CreateClick != null)
    {
        CreateClick(sender, e);
    }
 }
 
  //Calling the Event trigger after action completed in User control
 protected void btnCreateCtrl_Click(object sender, EventArgs e)
 {
    //your code here then trigger the event
    CallParentEvent(sender, e);
 }
  

3.       Now register the User Control in your Parent page or control, while registering provide the Event Handler method for our custom event.
Below is the Parent Control page. You can also behind the Event handler in Page load in code behind.
 
<SP:CreateCtrl id="createCtrl" runat="server" OnCreateClick="CreateCtrl_Click"/>
 
 

4.       Now in the Parent control code behind, call the respective method inside the above mentioned Event Handler (CreateCtrl_Click)
 
protected void CreateCtrl_Click(object sender, EventArgs e)
{
    try
    {
        //Call the respective in Parent control
    }
    catch (Exception ex)
    {
    }
}
 

 

Friday, August 16, 2013

Get Social tags in SharePoint 2010

Social Tagging in SharePoint really helps in categorizing the information upon User’s interest with meaningful tag and also improves the quality of search and sharing the data with others.

SocailTagManager is a sealed class which contains the methods and properties used to handle social Tag data.
We are going to use GetTags method from SocialTagManager class which returns all the Tags based on the Item URL or User Profile. To know all the methods and preoperties of SocialTagManager class click here.
(Check inline comments for more details).
   
var type = typeof(SocialTagManager);
var methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Instance);
 
// Get the method from SocialTagManager sealed class which returns all the Tags
var method = methods.FirstOrDefault(m => m.ToString() == "Microsoft.Office.Server.SocialData.SocialTag[] GetTags(System.Uri, Int32, Microsoft.Office.Server.SocialData.SocialItemPrivacy)");
if (method != null)
{
SPServiceContext serviceContext = SPServiceContext.GetContext(ospWeb.Site);
SocialTagManager stm = new SocialTagManager(serviceContext);
 
// Get page URL
Uri uri = new Uri(listItemURL);
 
// Retrieve only the public tags
var itemTags = (SocialTag[])method.Invoke(stm, new object[] { uri, 1000, SocialItemPrivacy.PublicOnly });
 
// Get the count of the selected tag.
likeCount = itemTags.Count(t => t.Term.Name.ToLower() == "i like it");
 
// Filter the tags with the selected tag
var socialTags = itemTags.Where(t => t.Term.Name.ToLower() == "i like it");
 
string username ="";
foreach (var socialTag in socialTags)
{
    // Each tag will be mapped with the Profile ID
    var user = socialTag.Owner;
    string personalSite = user.PublicUrl.AbsoluteUri;   
    username = username + ";" + user.DisplayName;
}
 

 

Get Document Icon Image in SharePoint

While we Query the Documents from the Library and list out the items with the Custom branding in the Webpart, Users expects to see the related icon for the document to easily segregate and recognize the document. SharePoint makes it easier with a method in SPUtility class called SPUtility.MapToIcon() which gets the document icon file name, which is being used in SharePoint. These icons are stored in 14 hive images folder.

string docicon = SPUtility.ConcatUrls("/_layouts/images",
SPUtility.MapToIcon(item.Web, SPUtility.ConcatUrls(item.Web.
Url, item.Url), "", IconSize.Size16));
SPUtility.MapToIcon() method retrieves the document from a XML file called “Docicon.xml” which maintains the mapping for the document icons with the extension files under 14 hive XML folder. We can also use the same XML file to get the respective icon for the Document based on the document extension. In case if you are listing the documents from some other source other than document library.
   
  private string ReturnExtension(string fileExtension)
  {
     XmlDocument document = new XmlDocument();
 
     document.Load(SPUtility.GetGenericSetupPath(string.Empty) + @"\TEMPLATE\XML\DOCICON.XML");
 
     XmlNodeList xnList = document.SelectNodes("//DocIcons/ByExtension/Mapping[@Key='" + fileExtension.ToLower() + "']");
 
            string returnURL = "";
            if (xnList.Count > 0)
            {
                foreach (XmlNode xn in xnList)
                {
                    returnURL = xn.Attributes["Value"].Value;
                    break;
                }
            }
            else
            {
                returnURL = "icgen.gif";
            }
            return returnURL;
  }
 

Get User Profile properties in SharePoint

User Profile Service application maintains User Profiles for all the Users in SharePoint and synchronizes with the Active Directory or with your Custom DB based on the configuration. If you want to access the User Profile properties from Web Application make sure your Web Application is configured with any of the User Profile Service application.

Check here to see Creation of User Profile Service application.
Follow below steps to check the Service connections.
1.       Navigate to Central Administration à Application Management à Manage Web applications
2.       Select your Web Application and Click on the Service Connections from Ribbon.

 
3.       Make sure User Profile Service application is selected from the list and click OK. 

To access a specific user profile, we need call the UserProfileManager class to create an object  for the UserProfile and to get the Properties of the User from the User Profile Database.

   
SPSecurity.RunWithElevatedPrivileges(delegate()
 {
    using (SPSite site = new SPSite(web.Url))
    {
      using (SPWeb objWeb = site.OpenWeb())
      {
         string strDisplayName = string.Empty;
         string strMySiteURL = string.Empty;
         string strEmail = string.Empty;
         SPServiceContext sc = SPServiceContext.GetContext(web.Site);
 
         //Get the User Profile Service configured to the current site
         UserProfileManager objUserProfileManager = new UserProfileManager(sc);
         UserProfile profile = null;
                           
         //Check whether the specified User exists in the UserProfile
         if (objUserProfileManager.UserExists(accountName))
         {
             //Get the User Profile using the Profile Manager
             profile = objUserProfileManager.GetUserProfile(accountName);
           
             //Now you can get all the Properties of the User from this object
             strDisplayName = profile.DisplayName;
             strMySiteURL = profile.PublicUrl.ToString();
             strEmail = profile[“WorkEmail”].Value();
         }
      }
    }                           
 });
            
 

If you need full access for all the User Profiles, you need to have “Manage User Profile” rights. By default, everyone will have read access to all the User Profiles.

Thursday, August 15, 2013

Calling JavaScript method from Server Side under Update Panel Postback

When you try to use the normal way of Calling a JavaScript method from Sever side in a Update Panel Postback, your JavaScript method will never be called. Since Update Panel makes Asynchronous calls you need to use “ScriptMananger” to register your client script from code behind instead of Page.ClientScript.

If your registering the Script under Update Panel Postback use the below line to register your client script.

ScriptManager.RegisterStartupScript(updatepanelID, updatepanelID.GetType(), "Reset", "MethodName();", true);
If your registering the Script under normal Postback use the below line to register your client script.

Page.ClientScript.RegisterStartupScript(this.GetType(), "Reset", "MethodName();", true);

Wednesday, August 14, 2013

Copy ListItem Unique Permission between Lists in SharePoint 2010 using C#

In some cases, we may need to copy List Items from one list to another list including the Permissions. So while copying the ListItem to the new List, by Default Parent permissions will be inherited to the newly created Items which is called as Role Inheritance. To copy the unique permissions also, first we need to break the Role Inheritance and copy the permissions as well.

Below  is the simple example, where we have same lists resides in two different site collections and now we are copying the Unique permissions from one list to another list.
 class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Console.Write("Source Site URL:");
                string srcSiteUrl = Console.ReadLine();
                Console.Write("Source List Name:");
                string srcListName = Console.ReadLine();
                Console.Write("Target Site URL:");
                string tgtSiteUrl = Console.ReadLine();
                Console.Write("Target List Name:");
                string tgtListName = Console.ReadLine();
                using (SPSite srcSite = new SPSite(srcSiteUrl))
                {
                    SPWeb srcWeb = srcSite.OpenWeb();
                    SPList srcList = srcWeb.Lists[srcListName];
                    Collection itemCollecInfo = srcList.GetItemsWithUniquePermissions();
                    if (itemCollecInfo.Count > 0)
                    {
                        using (SPSite tgtSite = new SPSite(tgtSiteUrl))
                        {
                            SPWeb tgtWeb = tgtSite.OpenWeb();
                            SPList tgtList = tgtWeb.Lists[tgtListName];
                            foreach (SPListItemInfo itemInfo in itemCollecInfo)
                            {
                                SPListItem srcItem = srcList.GetItemById(itemInfo.Id);
                                SPListItem tgtItem = tgtList.GetItemById(itemInfo.Id);
                                foreach (SPRoleAssignment roleAssign in srcItem.RoleAssignments)
                                {
                                    SPSecurity.RunWithElevatedPrivileges(delegate
                                    {
                                        if (tgtItem != null)
                                        {
                                            tgtItem.BreakRoleInheritance(false);
                                            tgtItem.RoleAssignments.Add(roleAssign);
                                            Console.WriteLine("Item ID: " + tgtItem.ID + " Roles Copied: " + roleAssign.Member);
                                        }
                                    });
                                }
                            }
                        }
                    }
                }
                Console.ReadLine();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error Occurred: " + ex.Message);
                Console.ReadLine();
            }
        }
    }

Custom Field type in SharePoint 2010

Custom Field for Uploading Documents and Images:

Scenario:

A Custom List has a column for Image and Document URL which is of type Hyperlink or Picture; it is used to store the URL of the Document or Image.
 In order to add an item to this list, we need to perform two steps.
1.       Upload the Picture or Document to some Library
2.       Copy the URL of the uploaded Item and Paste them in the “Hyperlink or Picture” field.
This seems to be a tedious process and looking for an option to upload Image or Document in the same page of Custom List Add Item/Edit Item form. 

Solution:


To reduce the two step process, we have created a Custom field type. This Custom Field type allows us to upload the Image/ Document directly in the Custom list Dialog box itself, which generates a thumbnail/link to show the Image/Document in the list view respectively. If we click on the thumbnail a popup with the real size picture will open and a Link to download the Document.
We have created an option to configure the default Document or Image library in the List settings, which is used to store all the Documents/Images and a reference to this document will be maintained in the list column.

Column types


1.       Enhanced Hyperlink - Field to upload the Documents to the respective Document Library selected in the List settings.
2.       Enhanced Image – Field to upload the Images to the respective Image Library selected in the List settings.

Implementation:


1.       Create a public custom field type class, which inherits from one of the built-in field type classes, such as SPFieldBoolen, SPFieldChoice, or SPFieldText and name it as ImageEnhancerField.cs.
2.       Create another Class file which needs to inherit from BaseFieldControl and name it as ImageEnhancerFieldControl.cs.
3.       Add SharePoint mapped folders to Control Templates and XML.
4.       Create a User Control under Control Templates folder and name it as ImageEnhancerFieldControl.ascx.
Note: User Control must be deployed directly under Control Templates and not in any sub-folders.      
5.       Create an XML file known as the field type deployment file under XML folder and name it as fldtypes_ImageEnhancer.xml.

Creating the Custom Field Class:  [ImageEnhancerField.cs]


1.       Inherit the Class from SPFieldText and add two public constructors using specific parameter list signatures and forward parameters to base class constructors with matching signatures.

class ImageEnhancerCustomField: SPFieldText
    {
//constructors
public ImageEnhancerCustomField (SPFieldCollection fields, string fieldName)
            : base(fields, fieldName)        { }
         public ImageEnhancerCustomField (SPFieldCollection fields, string typeName, string displayName)
            : base(fields, typeName, displayName)        { }


2.       Override the FieldRenderingControl property and define the get value.

public override BaseFieldControl FieldRenderingControl
        {
            get
            {
                SPContext.Current.List.EnableAttachments = false;
                BaseFieldControl fieldControl = new ImageEnhancerControl();
                fieldControl.FieldName = this.InternalName;
                return fieldControl;
            }
        }


3.       Then Override the GetValidatedString method and return the value which needs to store in the Field.

public override string GetValidatedString(object value)
     {
        return value.ToString().ToUpper();
     }

Creating FieldControl.ascx [ImageEnhancerFieldControl.ascx]


SharePoint Rendering Template can work only when we place the ascx file directly under Control Templates folder not into any sub folders. [Please check comments inside]

<SharePoint:RenderingTemplate Id="ImageEnhancerControlRender" runat="server">
   
    <Template>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate>
<!-- To show the preview of the image in Edit form -->
    <asp:Image ID="ImgThumb" runat="server" />
<!-- To browse to the file from the physical location -->
        <asp:FileUpload runat="server" id="flUpload" size="40"/>  
<!-- To Delete the Image reference in the Edit form -->
        <asp:Button runat="server" ID="btnDelete" Text="Delete"/>
<!-- To validate the Type of File uplodaed -->
        <asp:RegularExpressionValidator runat="server" ErrorMessage="Please upload png,jpeg or gif files only" ControlToValidate="flUpload" id="ImgRegularExpressionValidator" validationexpression="^.+\.(png|jpeg|jpg|gif)$" SetFocusOnError="True"></asp:RegularExpressionValidator> 
<!-- To Error Message in case of any issues -->
                     
        <asp:Label runat="server" id="lblMessage" />
        <asp:Label runat="server" id="lblMessage2" />
        <asp:Label runat="server" id="lblMessage3" />
         </ContentTemplate>
</asp:UpdatePanel>
    </Template>
</SharePoint:RenderingTemplate>

Creating Custom Field Control Class [ImageEnhancerFieldControl]


1.       Inherit the Class from BaseFieldControl and override the DefaultTemplateName property and define the get property value.

protected override string DefaultTemplateName
        {
            //Name of the SharePoint Rendering Template defined in the ascx file.
            get { return "ImageEnhancerControlRender"; }
        }

2.       Override the Value property and define the get & set values. The Value of this field will be stored in this format “File location full path, Thumbnail URL”.

public override object Value
        {
            get
            {
                EnsureChildControls();
               
                    if (hasfile)
                    //if it’s a new file return the path to the file and the path to the thumbnail
                    return httppath + filename + " ," + thumbnailpath;
                else
                {
                    if (!ImgThumb.Visible)
                    {
                        //if it’s going to be erase return a blank string
                        return "";
                    }
                    else
                    {   //if it’s not been modified return the current string
                        return Field.FieldRenderingControl.ItemFieldValue;
                    }
                }               
            }
            set
            {
                try
                {
                    EnsureChildControls();
                    if (!value.ToString().Equals(",") || !value.ToString().Equals(""))
                    {
// Setting the Image thumbnail url to the Image control added earlier
                        ImgThumb.ImageUrl = value.ToString().Substring(value.ToString().IndexOf(',') + 1);
//Setting the Image control and Delete button control visible in Edit Form if value exists
                        ImgThumb.Visible = true;
                        btnDelete.Visible = true;
                    }
                    else
                    {
                        ImgThumb.Visible = false;
                        btnDelete.Visible = false;
                    }
                }
                catch { }
            }
        }

3.       Now define the control how should it behave in New Form, Display Form and Edit Form of List Item [Check the inline comments for description].

protected override void CreateChildControls()
        {
            try
            {
                if (Field == null) return;
                base.CreateChildControls();
                if (ControlMode == Microsoft.SharePoint.WebControls.SPControlMode.Display) return;
                if (ControlMode == SPControlMode.New || ControlMode == SPControlMode.Edit)
                {
                    Stream fs = null;
// As we set the Default Template name to the name of SharePoint rendering template name defined in ascx file.
// Now get the instance all the controls from the TemplateContanier.
                    flUpload = (FileUpload)TemplateContainer.FindControl("flUpload");
                    lblMessage = (Label)TemplateContainer.FindControl("lblMessage");
                    lblMessage2 = (Label)TemplateContainer.FindControl("lblMessage2");
                    lblMessage3 = (Label)TemplateContainer.FindControl("lblMessage3");
                    ImgThumb = (Image)TemplateContainer.FindControl("ImgThumb");
                    btnDelete = (Button)TemplateContainer.FindControl("btnDelete");
                    txtValue = (TextBox)TemplateContainer.FindControl("txtValue");
                    btnDelete.Click += new EventHandler(btnDelete_Click);
                    try
                    {
                        SPContext.Current.Item[Field.Title].Equals("null");
                    }
                    catch (Exception E)
                    {
                        ImgThumb.Visible = false;
                        btnDelete.Visible = false;
                    }
// Checking whether the File upload control has any file
                    if (flUpload.HasFile)
                    {
//Checking the File Content Length
                        if (flUpload.PostedFile.ContentLength <= 524288)
                        {
                            fs = flUpload.PostedFile.InputStream;
                            filename = flUpload.FileName;
                            hasfile = true;
                            flUpload.EnableViewState = false;
                            flUpload = filenull;
                            flUpload.Dispose();
                            flUpload.Enabled = false;
                            fileSize = 0;
                            //TemplateContainer.fin
                        }
                        else
                        {
                            hasfile = true;
                            fileSize = 1;
                            return;
                        }
                    }
                    flUpload.TabIndex = TabIndex;
                    flUpload.CssClass = CssClass;
                    flUpload.ToolTip = Field.Title + " Image";
// Checking the Default Image library is defined or not. We can define the library in List settings.
                    System.Collections.Specialized.NameValueCollection PictureLibrarys;
                    PictureLibrarys = SharepointInformation.QueryCustType(SPContext.Current.Web.Url.ToString(), SPEncode.UrlDecodeAsUrl(SPContext.Current.List.ToString()), "CustomImageStorage", "ImageEnhancerCustomField",Field.Title);
                    if (PictureLibrarys[0].Equals("False"))
                    {
                        flUpload.Enabled = false;
                        lblMessage.Text = "Image cannot be uploaded as no Picture Library is associated with this list. In order to setup Picture Library, go to ";
                        lblMessage2.Text = "'List Settings - General Settings - Enhanced Image / Document Library' ";
                        lblMessage3.Text = "and select existing Picture Library";
                        //lblMessage3.ForeColor = "Red";
                        //lblMessage.ForeColor = "Red";
                        //lblMessage2.ForeColor = "Red";
                        lblMessage.Font.Bold = true;
                        lblMessage2.Font.Bold = true;
                        lblMessage3.Font.Bold = true;
                        lblMessage2.Font.Italic = true;
                        }
                    else
                    {
                        flUpload.Enabled = true;
                        if (lblMessage != null)
                            lblMessage.Visible = false;
                    }
                    //IF THE UPLOAD FIELD HAS INFORMATION
                    if (hasfile)
                    {
                       
                        bool exist = false;
                        if (PictureLibrarys.HasKeys())
                            for (int i = 0; i < PictureLibrarys.Count; i++)
                            {
                                if (PictureLibrarys.GetKey(i).Equals(Field.InternalName) || PictureLibrarys.GetKey(i).Equals(Field.Title))
                                {
                                    exist = true;
                                    break;
                                }
                            }
                        if (exist)
                        {
// Uploads the File to the SharePoint Image library defined in the List settings if File exist.
                            thumbnailpath = SharepointInformation.UploadImage(SPContext.Current.Web.Url.ToString(), fs, PictureLibrarys[Field.Title], "", filename, SPContext.Current.Web);
                           
                            httppath = SPContext.Current.Web.Lists[PictureLibrarys[Field.Title]].ParentWebUrl.ToString() + "/" + SPContext.Current.Web.Lists[PictureLibrarys[Field.Title]].RootFolder.Url + "/";
                        }
                        else
                        {
                            thumbnailpath = "Go to List Settings - Enhanced Image Settings";
                        }
                    }
                }
                
            }
            catch (Exception spe)
            {
                int i = 0;
            }
        }

Creating Field type Deployment file [fldtypes_ImageEnhancer.xml]


Open fldtypes_ImageEnhancer.xml file and copy the below code [Check the inline comments for description].

<?xml version="1.0" encoding="utf-8"?>
<FieldTypes>
       <FieldType>
//Define the Field Type Name here
              <Field Name="TypeName">ImageEnhancerCustomField</Field>
//Define the Parent Type from the new type is getting Inherited
              <Field Name="ParentType">Text</Field>
//Provide the Display name for the Field
              <Field Name="TypeDisplayName">Enhanced Image</Field>
              <Field Name="TypeShortDescription">Enhanced Image</Field>
              <Field Name="UserCreatable">TRUE</Field>
//Specify where all this column should be available
              <Field Name="ShowInListCreate">TRUE</Field>
              <Field Name="ShowInSurveyCreate">TRUE</Field>
              <Field Name="ShowInDocumentLibrary">TRUE</Field>
              <Field Name="ShowInColumnTemplateCreate">TRUE</Field>
              <Field Name="Sortable">TRUE</Field>
              <Field Name="Filterable">TRUE</Field>
// Specify the NameSpace and class details where the implementation is done
              <Field Name="FieldTypeClass">EnhancedPicture.ImageEnhancerCustomField, EnhancedPicture, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b5ecf5690ed59344</Field>
              <Field Name="SQLType">nvarchar</Field>
//Below part is to define how the field should appear in Display Form
              <RenderPattern Name="DisplayPattern">
                     <Switch>
                           <Expr>
                                  <Column />
                           </Expr>
                           <Case Value="" />
                           <Default>
                                  <HTML>
                                  <![CDATA[<SCRIPT>  function PopupPic(sPicURL) { window.open( "/_layouts/EnhancedPicture/popup.aspx?"+sPicURL, "", "HEIGHT=50,WIDTH=50"); }  var path=']]>
          </HTML>                               <Column/>
                                  <HTML>
                                         <![CDATA['; if (path != "," || path != "" || path != " ") {var xsep=path.lastIndexOf(','); var lastind=path.length;                                        document.write("<a href=\"javascript:PopupPic('" + path.substring(0,xsep) + "')\">                                      <IMG border=0 SRC='"+ path.substring(xsep+1,lastind)+"' ALT='" +                                       path.substring(xsep+1,lastind) + "' > </a>");}</SCRIPT>]]>
                                  </HTML>             
                           </Default>
                     </Switch>
              </RenderPattern>
       </FieldType>
</FieldTypes>

 Once we deploy the XML file, we can see the New Field Type in Create Column of the List.

Configuring Image/Document Library:


To configure the default Image/Document library where the Images and Documents needs to be uploaded, Navigate to List Settings à Enhanced Image / Document Library.


Select the Image and Library from the dropdown and Click Accept button. Once the Accept button is clicked we are updating Fields XML of this current list with the selected libraries.


To Add a link under General Settings in List settings page deploy the below Elements.xml.

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <CustomAction
       Id="ImageEnhacer"
       GroupId="GeneralSettings"
       Location="Microsoft.SharePoint.ListEdit"
       Sequence="20"
       Title="Enhanced Image / Document Library"
       RequireSiteAdministrator="TRUE"
       >
    <UrlAction Url="~site/_layouts/EnhancedPicture/PicturePicker.aspx?&amp;siteId={SiteUrl}&amp;listId={ListId}&amp;itemId={ItemId}"/>
  </CustomAction>
</Elements>

 New Item Form
In New Item form we can browse through the file which needs to be uploaded and click on the Save button.



Once the Item is saved, selected document will be uploaded to the respective library and these New Columns will have a reference to the Document / Image. 

Navigate to the Libraries selected in settings page to verify the uploaded Document / Image.


View Item Form

In the View Item Form, we can see the Thumbnail image for the Image field type and a Link to the document for Hyperlink field type



Once clicking on the thumbnail, we can see the Full Image. Upon clicking on the link, document will be downloaded.

Edit Item Form

In Edit Item Form, we can change the Document/Image reference by clicking the Delete button, which will remove the reference and we can upload a new Item.

Related Posts Plugin for WordPress, Blogger...