Archive

Posts Tagged ‘web parts’

SharePoint 2010: Configuring incoming emails on a Production Environment (non-Exchange Server)

September 17, 2012 1 comment

Recently I needed to setup incoming emails on a SharePoint 2010 site sadly, after researching this subject a lot, I was not able to find a blog that provided a complete answer of how to set this up on a Production Environment. There are some variations in the way this can be setup but the method I will be explaining in this blog involves a non-Exchange Server method.

Assumptions

I am assuming that:

  • You have setup an SMTP server on one of your SharePoint WFE’s (Web Front End) if you are not sure on how to do this then please check out this post.
  • You have a domain name registered and that you can modify the DNS records

The Solution

The solution involves:

  • Setting up the DNS Records
  • Configuring the SMTP Server
  • Configuring Central Administration
  • Configuring a SharePoint List

Setting up the DNS Records

In this example I am using a domain name: http://www.shareheaven.co.uk that is registered with GoDaddy.com.

Login to your domain name’s control panel and add a DNS A (Host) record in the following format:

Setting up a DNS A (Host) Record

Where the host (‘notify’ in this example) can be anything of your liking. The IP address should be the IP address of the server that hosts the SMTP Server.

Next we need to add a DNS MX Record in the following format:

Setting up the MX Record

Wait for the DNS changes to take effect, you can use this website to check if the changes have taken effect.

Configuring the SMTP Server

On the SMTP Server we will need to add an alias. Open IIS 6.0 Manager > Expand your SMTP Server in the list on the left hand side > Right click on ‘Domains’ > New > Domains.

SMTP Alias Setup

On this screen (screen shot above) select Alias and click Next and then fill it out as below (based on your domain name):

Creating an alias

Configuring Central Administration

Next we need to setup Central Administration to enable incoming emails in our SharePoint Farm, in Central Admin browse to System Settings > Configure incoming e-mail settings and set it up as below:

Central Administration Setup

Configuring a SharePoint List

Finally, we can now setup a SharePoint List to receive incoming emails. In this example I will be setting up a Document Library to receive incoming emails. Browse to Library Settings > Incoming e-mail settings of the SharePoint List you would like to setup to receive incoming emails. Fill out the form as below and click ‘OK’:

Configure the SharePoint List

Testing the Solution

To test the solution send an email to the email address we setup to receieve incoming emails which in our example was: test@shareheaven.co.uk (replace shareheaven with your domain name of course!):

Sending the email

Screen shot below shows the .eml file arriving in the drop folder of the SMTP Server:

Mail drop folder

A SharePoint Timer Job picks up this email, processes it and then adds an item in the Document Library:

Document Library Item Added

Advertisements

SharePoint 2010: Custom action that executes custom code

November 21, 2010 18 comments

In 2007 it was possible to create a custom action and then link it to some code.

You did this by first declaring your custom action in an elements.xml file (which you would then deploy as part of a feature):

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <CustomAction
    Id="MyCustomAction"
    RegistrationType="List"
    GroupId="ActionsMenu"
    Location="Microsoft.SharePoint.StandardMenu"
    Sequence="1000"
    ControlAssembly="[Fully qualified assembly name]"
    ControlClass="MyNamespace.MyCustomAction">
  </CustomAction>
</Elements>

In the ControlAssembly and ControlClass attributes you specified your custom assembly and your custom class (a WebControl) that contained your custom code.

Then you created your custom WebControl:

public class MyCustomAction : WebControl 
{
    protected override void CreateChildControls() 
    {
        // Do some stuff
    }
}

Using this way we were able able to execute some custom code when someone clicked our custom action.

However, it seems that we cannot use this method in SharePoint 2010 although there are a few workarounds to achieve the same result. Below I will show you a way I used.

To start off with, I created an elements.xml file with the following declaration:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <CustomAction Id="ContentTypeRibbonCustomization" RegistrationId="10005" RegistrationType="List" Location="CommandUI.Ribbon.ListView" Sequence="95" Title="Run Custom Code">
    <CommandUIExtension>
      <CommandUIDefinitions>
        <CommandUIDefinition Location="Ribbon.List.Settings.Controls._children">
          <Button Id="ContentTypeTest.Button" Image16by16="/_layouts/images/LSTPEND.gif" Image32by32="/_layouts/images/centraladmin_configurationwizards_farmconfiguration_32x32.png" Command="ContentTypeCommand" CommandType="General" Description="Runs some custom Code" TemplateAlias="o2" Sequence="95" LabelText="Perform My Action"/>
        </CommandUIDefinition>
      </CommandUIDefinitions>
      <CommandUIHandlers>
        <CommandUIHandler Command="ContentTypeCommand" CommandAction="/MyWeb/_layouts/CustomPages/MyCustomApplicationPage.aspx" />
      </CommandUIHandlers>
    </CommandUIExtension>
  </CustomAction>
</Elements>

This specifies that my Custom Action will appear on my custom list with TemplateType of 10005 (specified in the RegistrationId attribute) in the list view section.

I then used a Feature to depoy my Custom Action.

All my Custom Action does is to send the user to a custom page that is located in the Layouts folder:

/MyWeb/_layouts/CustomPages/MyCustomApplicationPage.aspx

I then created my custom aspx page. Below is the mark up for the page:

<%@ Assembly Name="MyCustomAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e246903334b3e97b" %>
<%@ Page Language="C#" AutoEventWireup="true" Inherits="MyCustomNamespace.MyCustomControl"
    Debug="true" %>

And finally, below is the code behind for the aspx page:

namespace MyCustomNamespace
{
    public class MyCustomControl: UserControl
    {    
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            // run some custom code
            // then redirect the user back to the original page
        }
    }
}

Using this way I was able to link some custom code that would execute in response to someone clicking my custom action.

For everything you need to know about customising the SharePoin Ribbon please go here to Chris O’Brien’s blog post.

After spending a lot of time investigating how to customise the Ribbon to meet the requirements I had I can safely say this is by far the best and most comprehensive blog post I found on the net.

As I said earlier there are other ways you can use to achieve the same objective. You can easily link a custom action to execute some javascript function. I guess one option would be to link it to a javascript function that then invoked some server side code. I havent tried this myself so I cannot say for sure if this approach would work.

If you had a similar issue to the one I had above, I would be interested in hearing what approach you used to resolve it (if different to the approach I used).

How to change the Author of a Document that is stored in a Document Library?

April 20, 2009 3 comments

Apparently there is’nt a straight forward way to achieve this. Below is how you can do it though:

SPList list = web.Lists[“myList”];

list.Fields[“Author”].ReadOnlyField = false;

SPListItem item = list.Items.Add();

item[“Author”] = “value”;

item.SystemUpdate(false);

list.Fields[“Author”].ReadOnlyField = true;

WebPartPages: Programmatically adding a new web part page

April 5, 2009 3 comments

How do you add a WebPartPage or a BasicPage programmatically?

WebPartPages are stored in document libraries. It is simply a matter of adding the page to the document library you want. However, if you need to add a WebPartPage programmatically the same way SharePoint allows you to do via the UI then you can use the following method:


private void AddWebPartPage(string fileTitle, SPWeb web, SPList list, int webPartPageTemplate, string pageType, string folder)
{
    string postInformation =
    "<?xml version="1.0" encoding="UTF-8"?>" +
    "<Method>" +
    "<SetList Scope="Request">" + list.ID + "</SetList>" +
    "<SetVar Name="ID">New</SetVar>" +
    "<SetVar Name="Cmd">NewWebPage</SetVar>" +
    "<SetVar Name="Type">" + pageType + "</SetVar>" +
    "<SetVar Name="WebPartPageTemplate">" + webPartPageTemplate + "</SetVar>" +
    "<SetVar Name="Title">" + fileTitle + "</SetVar>" +
    "<SetVar Name="Overwrite">true</SetVar>" +
    "</Method>";
    string processBatch = web.ProcessBatchData(postInformation);
    if (processBatch.Equals("<Result ID="" Code="0">rn</Result>n"))
    {
        SPFile file = web.GetFile(list.RootFolder.Url + "/" + fileTitle + ".aspx");
        //if page was in subfolder then move it there
        if (!String.IsNullOrEmpty(folder))
        {
            file.MoveTo(fileTitle,
true);
        }
    }
}

Below are the WebPartPage templates you can specify:

  1. Full Page, Vertical
  2. Header, Footer, 3 Columns
  3. Header, Left Column, Body
  4. Header, Right Column, Body
  5. Header, Footer, 2 Columns, 4 Rows
  6. Header, Footer, 4 Columns, Top Row
  7. Left Column, Header, Footer, Top Row, 3 Columns
  8. Right Column, Header, Footer, Top Row, 3 Columns

Type could have the following possible values:

  1. WebPartPage
  2. BasicPage

For further details click here.

ListViewWebPart: Programmatically setting the ToolbarType property

April 5, 2009 10 comments

While working on a migration project we came across a requirement whereby ListViewWebPart’s had to be added to a page programmatically. The ListViewWebPart class has a property called toolbartype. Setting the toolbartype property sounds simple enough. I mean how difficult can it be to set a property?

The problem is that it is a read only property. We thought maybe we can set it via reflection. After searching a bit on google we found a couple of suggestions on how it could be done (most of them were solutions on how to set it to none). One method seemed to have solved our problem until we installed the latest infrastructure updates. Then it completely stopped working. However luckily for us Tony Stegeman and Brian Farhill came up with a solution.

Below you can see the complete solution that worked for us:


private static void SetToolbarType(SPView spView, string toolBarType)
{
    spView.GetType().InvokeMember(
"EnsureFullBlownXmlDocument",
    BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod,
    null, spView, null, System.Globalization.CultureInfo.CurrentCulture);
    PropertyInfo nodeProp = spView.GetType().GetProperty("Node",
    BindingFlags.NonPublic | BindingFlags.Instance);
    XmlNode node = nodeProp.GetValue(spView, null) as XmlNode;
    XmlNode toolbarNode = node.SelectSingleNode("Toolbar");
    if (toolbarNode != null)
    {
        toolbarNode.Attributes[
"Type"].Value = toolBarType;
        // If the toolbartype is Freeform (i.e. Summary Toolbar) then we need to manually 
        // add some CAML to get it to work.
        if (String.Compare(toolBarType, "Freeform", true, System.Globalization.CultureInfo.InvariantCulture) == 0)
        {
            string newItemString = "";
            XmlAttribute positionNode = toolbarNode.OwnerDocument.CreateAttribute("Position");
            positionNode.Value =
"After";
            toolbarNode.Attributes.Append(positionNode);
            switch (spView.ParentList.BaseTemplate)
            {
                case SPListTemplateType.Announcements:
                    newItemString =
"announcement";
                    break;
                case SPListTemplateType.Events:
                    newItemString =
"event";
                    break;
                case SPListTemplateType.Tasks:
                    newItemString =
"task";
                    break;
                case SPListTemplateType.DiscussionBoard:
                    newItemString =
"discussion";
                    break;
                case SPListTemplateType.Links:
                    newItemString =
"link";
                    break;
                case SPListTemplateType.GenericList:
                    newItemString =
"item";
                    break;
                case SPListTemplateType.DocumentLibrary:
                    newItemString =
"document";
                    break;
                default:
                    newItemString =
"item";
                    break;
            }
            if (spView.ParentList.BaseType == SPBaseType.DocumentLibrary)
            {
                newItemString =
"document";
            }
            // Add the CAML
            toolbarNode.InnerXml = @"<IfHasRights><RightsChoices><RightsGroup PermAddListItems=""required"" /></RightsChoices><Then><HTML><![CDATA[ <table width=100% cellpadding=0 cellspacing=0 border=0 > <tr> <td colspan=""2"" class=""ms-partline""><IMG src=""/_layouts/images/blank.gif"" width=1 height=1 alt=""""></td> </tr> <tr> <td class=""ms-addnew"" style=""padding-bottom: 3px""> <img src=""/_layouts/images/rect.gif"" alt="""">&nbsp;<a class=""ms-addnew"" ID=""idAddNewItem"" href=""]]></HTML><URL Cmd=""New"" /><HTML><![CDATA["" ONCLICK=""javascript:NewItem(']]></HTML><URL Cmd=""New"" /><HTML><![CDATA[', true);javascript:return false;"" target=""_self"">]]></HTML><HTML>Add new " + newItemString + @"</HTML><HTML><![CDATA[</a> </td> </tr> <tr><td><IMG src=""/_layouts/images/blank.gif"" width=1 height=5 alt=""""></td></tr> </table>]]></HTML></Then></IfHasRights>";
        }
        spView.Update();
}

Programmatically getting the SPField object you just added

April 3, 2009 3 comments

When you add an SPField to an SPList programmatically using the SharePoint Object Model you can get the SPField object representing the newly added field via SPList.Fields[string displayName]. But this assumes that no other field with the same display name as the newly added SPField exists in the SPList.

The work around is listed below:

 

Guid fieldGuid = Guid.NewGuid();
string newFieldCAML =
 "<Field Type="Text" DisplayName="MyNewField" ID="+fieldGuid+"/>";
splist.Fields.AddFieldAsXml(newFieldCAML, false, SPAddFieldOptions.AddFieldInternalNameHint);
SPField newField = spList.Fields[fieldGuid];

You can use the AddFieldAsXml to add the new SPField. It takes a CAML string as a parameter in which you can specify your own Guid. Later you can use this Guid to retrieve the SPField you just added.

Meeting Workspace: How to programatically add tabs

April 3, 2009 1 comment

When you add a page via the UI it adds it as a WebPartPage to a hidden list called “Workspace Pages”. It also does something internally to create the Tab because simply progammatically adding the WebPartPage to the hidden list doesnt seem to work.

After spending a lot of time investigating this issue I finally found a solution. The solution is listed below:
 

string newPage = string.Empty;
Type cmType = typeof(SPMeeting);
SPMeeting mtg = (SPMeeting)
Activator.CreateInstance(cmType,
BindingFlags.NonPublic | BindingFlags.Instance,
null, null, System.Globalization.CultureInfo.CurrentCulture,
null);
Type t = mtg.GetType();
t.InvokeMember(
"m_Web", BindingFlags.NonPublic
|
BindingFlags.Instance | BindingFlags.SetField,
null, mtg, new Object[] { web });
mtg.AddPage(
"JunkYard", 1, out newPage);

The SPMeeting class has a method “AddPage”. This class has no public constructors therefore you cannot instantiate it the normal way. Once you instantiate it you need to set, via reflection, m_Web which is a private member and holds the SPWeb object. The final step is to call the AddPage method passing it the name of the page you want to add, an instanceid (not sure what this is), and an out string parameter.