Pages

Showing posts with label SharePoint 2013. Show all posts
Showing posts with label SharePoint 2013. Show all posts

Monday, June 16, 2014

Create HTTPModule Step Wise - Explained with CustomAccessDenied Page in SharePoint 2013

This post guides not only how to create a HTTPModule but also helps for further steps for my post on Custom Access Denied Page in SharePoint 2013.

For this you need to do three steps,

Step 1:- Add a new class file and extend that one from IHTTPModule. Then copy below code to your .cs file.

public class CustomAccessDenied : IHttpModule
    {
        public void Init(HttpApplication app)
        {
            app.PreRequestHandlerExecute += new EventHandler(app_PreRequestHandlerExecute);
        }
        void app_PreRequestHandlerExecute(object sender, EventArgs e)
        {
            HttpContext context = HttpContext.Current;
            string str = Path.GetFileName(new Uri(context.Request.Url.AbsoluteUri).LocalPath);

            if (str.ToLower().Equals("accessdenied.aspx"))
            {
                string strSourceURL = context.Request.RawUrl.ToString();
                strSourceURL = strSourceURL.ToLower().Replace("accessdenied", "customaccessdenied");
                context.Response.Redirect(strSourceURL , true);
            }
        }

        public void Dispose()
        {
        }
    }

Step 2:- Now you need to enter in the Modules section in your web.config file. I would recommend to go with IIS UI. For this, select your website and find the Modules Section as below.




Step 3:- Click on this Modules, and in the right section you will find Add Managed Module Option. Click on that and add Name and Type as below.

For Eg:- Name as CustomAccessDenied
Type as {Your_NAMESPACE}.CustomAccessDenied, {Your_NAMESPACE} ,Version=1.0.0.0, Culture=neutral, PublicKeyToken={Value}

Click Ok.




If this .cs file is not in your existing solution and created separate C# Library Project, need to make sure that you have entry in SafeControls of your web.config file. I would recommend here also not to enter value manually but through VS. Go to Package in your VS Solution and Add the Assembly. Select as YES under safe controls  column. This way the value get enters in your web.config file.






Saturday, June 14, 2014

SharePoint 2013 June 2014 Cumulative Updates


     Issues that this cumulative update package fixes

  • When a SharePoint 2013 workflow sends an email message, the workflow context Current Item URL does not have the complete URL.
  • Assume that you publish an InfoPath form that contains an enhanced rich text column that immediately follows a multiple-selection choice column to a SharePoint list. When you browse to this SharePoint list by using a web browser other than Internet Explorer, the rich text column is always empty.

Thursday, June 12, 2014

SharePoint - Create and Delete Alerts on List Programatically

Generally when we require any action need to happen if we do any operation on List Items, we go with List Item Event Receivers. But if you have a requirement where just a notification need to go to some user with items added/changed, you can go with ALERTS in SharePoint which is OOB Feature.



In order to setup this on List, we dont have any way of declarative syntax[XML through Schema.xml]. We need to set this either Manually or through Programatically.

Let me explain you how to create and delete alerts on SharePoint List Programatically. In Google, you will able to get easily about how to Create alerts but I think I didn't find much info on Delete alerts. For this I will explain you both in below:-

Create Alerts:-

 private static void CreateAlert(SPUser user, SPList list)
        {
            SPAlert newAlert = user.Alerts.Add();
            //Here kept Alert Name same as List Name, but can give any Name
            newAlert.Title = list.Title;
            newAlert.AlertType = SPAlertType.List;
            newAlert.List = list;
            newAlert.DeliveryChannels = SPAlertDeliveryChannels.Email;
            newAlert.EventType = SPEventType.Add;
            newAlert.AlertFrequency = SPAlertFrequency.Immediate;
           //If we do False in below line, it will not send email notification to user when Alert has been sent.
            newAlert.Update(false);

        }

Delete Alerts:-

  private static void DeleteExistingAlert(SPWeb web, SPUser User, string strListTitle)
        {
            //Using this As we cant Delete in the Loop of Web.Alerts
            var col = new List<string>();
            foreach (SPAlert alert in web.Alerts)
            {
               // If You want to remove particular Alert, if not remove this If Condition
                if (alert.List.Title.Equals(strListTitle) 
                    && alert.Title.ToLower().Equals(strListTitle.ToLower()))
                {
                    col.Add(alert.ID.ToString());
                }
            }
            // If we use Delete Alert in above If Condition only, will get an error as Collection Cant be Modified
            foreach (var item in col)
            {
                web.Alerts.Delete(new Guid(item));
            }
        }

Once it gets Created, in order to verify you cant check in the same place of List All Items page. For this you need to go to Site Settings --> Click On User Alerts





Happy Programming..!

Tuesday, June 10, 2014

SharePoint Programming - Dont set or use AllowUnsafeUpdates Instead Use ValidateFormDigest

Generally in your daily SharePoint Programming, you may come across issue of 

The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again

To Fix this issue, if you googled many places it will be suggested as to set AllowUnsafeUpdates = true or false.

If you do above, it will not throw error and resolve the issue but it is not the right way. By setting AllowUnsafeUpdates you are allowing for security threats.

The best way is to use SPUtility.ValidateFormDigest()
  • In your Master Page or in your aspx page, place below tag
         <sharepoint:formdigest id=”FormDigest1″ runat=”server” />
  • Now in your .cs file, in your init method or before you use the SPSecurity.RunWithElevatedPrivileges, place below code line.
protected override void OnInit(EventArgs e)
{
if (Page.IsPostBack)
{
SPUtility.ValidateFormDigest();
base.OnInit(e);
}
}

                                          [OR]

SPUtility.ValidateFormDigest();
SPSecurity.RunWithElevatedPrivileges(delegate()
{....

Thursday, June 5, 2014

SharePoint List - Re Order Items with OOB Feature


This is a very common request from client when we do create them custom SharePoint lists. “How can I re-order the list?” In fact, you could create an extra column in your custom list via SharePoint Designer (SPD) or via your internet browser. Add a new column and have it as a “Number” field, name it “Display Order” and start identifying the order of each list item. Well, but we are going to use another way. The little trick I am going to show works perfectly in MOSS 2007, SharePoint 2010 and 2013.

For this, we can go with One of the SharePoint hidden pages which resides in Layouts Folder.  reorder.aspx page which will allows to re-order your list items. 

Specify {SiteUrl}/_layouts/Reorder.aspx?List={ListId}

Now you will see the List Items Displaying with its Only Title and a dropdown Column like below.

In SP 2013,

In SP 2010,


Once you the Order, it will get effected the List. But when you see in UI, you might still see the Items not displayed in order what you did in earlier step. For this, as by default in All Items Page, items are ordered by ID it will consider that one. Here I want to point that there is one Field named as ORDER which will be available as OOB field in any List and this will be in Hidden State.

Make this Hidden Field as Visible, using Powershell or if custom list adding in your schema.xml itself.

Using Powershell,

# Change List Schema to unhide order field.
$siteUrl = "yourSiteUrl;
$listTitle = "yourListTitle";
$site = Get-SPSite -Identity $siteUrl;
$web = $site.OpenWeb();
$list = $web.Lists[$listTitle];
$field=$list.Fields["Order"];
$field.SchemaXml=
$field.SchemaXml.Replace("Hidden=""TRUE""","Hidden=""FALSE""");
Write-Host "-------------------------------------"
Write-Host "Order field is set to visible in
list :  " $list.Title -foregroundcolor Green -nonewline
Write-Host " in the site  : " $site.Url -foregroundcolor Green
Write-Host "-------------------------------------"
$web.Dispose();
$site.Dispose();



If you are having your list in the visual studio solution you can add
<Field ID="{ca4addac-796f-4b23-b093-d2a3f65c0774}" ColName="tp_ItemOrder" RowOrdinal="0" Name="Order"
DisplayName="Order" Type="Number" Hidden="FALSE" SourceID="http://schemas.microsoft.com/sharepoint/v3"
StaticName="Order" FromBaseType="TRUE" /> 

to the <Fields> collection of the Schema.xml

Now go to your respective view settings and change the Sort by ORDER Column


Now go to your list and view the Items, you will observe all Items are in ORDER wise which you specified in ReOrder Page.

This way we can understood, where lot of things we can do able without coding/logic in SharePoint if we are in the SharePoint OCEAN...!

Wednesday, June 4, 2014

SharePoint Object Model Best Practices - Working with Lists and Folders

1.      Use SPList.GetItems instead of SPList.Items

Apply Filters, specify only fields needed to make the query more efficient. Apply pagination in increments of no more than 2000 items.
SPQuery query = new SPQuery();
SPListItemCollection spListItems ;
string lastItemIdOnPage = null; // Page position.
int itemCount = 2000

while (itemCount == 2000)
{
    // Include only the fields you will use.
    query.ViewFields = "<FieldRef Name=\"ID\"/><FieldRef Name=\"ContentTypeId\"/>";  
    query.RowLimit = 2000; // Only select the top 2000.
    // Include items in a subfolder (if necessary).
    query.ViewAttributes = "Scope=\"Recursive\"";
    StringBuilder sb = new StringBuilder();
    // To make the query order by ID and stop scanning the table, specify the OrderBy override attribute.
    sb.Append("<OrderBy Override=\"TRUE\"><FieldRef Name=\"ID\"/></OrderBy>");
    //.. Append more text as necessary ..
    query.Query = sb.ToString();
    // Get 2,000 more items.

    SPListItemCollectionPosition pos = new SPListItemCollectionPosition(lastItemIdOnPage);
    query.ListItemCollectionPosition = pos; //Page info.
    spListItems = spList.GetItems(query);
    lastItemIdOnPage = spListItems.ListItemCollectionPosition.PagingInfo;
    // Code to enumerate the spListItems.
    // If itemCount <2000, finish the enumeration.
    itemCount = spListItems.Count;
}

2.      Instead of using SPList.Items.GetItemById, use SPList.GetItemById(int id, string field1, params string[] fields). Specify the item identifier and the field that you want.

3.      Use SPList.ItemCount instead of SPList.Items.Count.

4.      Use SPList.GetItemByUniqueId(System.Guid) instead of SPList.Items[System.Guid]

5.      Use SPList.GetItemById(System.Int32) instead of SPList.Items[System.Int32]

6.      Use SPList.GetItemById(System.Int32) instead of SPList.Items.GetItemById(System.Int32)

7.      Use SPWeb.Lists[GUID] or SPWeb.GetList(strURL) is preferable to using SPWeb.Lists[strDisplayName].

·         Using the GUID is preferable because it is unique, permanent, and requires only a single database lookup.

·         The display name indexer retrieves the names of all the lists in the site and then does a string comparison with them.


8.      Use DeleteByID method instead of Delete()

SPSite site = new SPSite("site url");
SPWeb web = site.OpenWeb();
SPList list = web.Lists["custom list name"];
SPListItem item = list.GetItemById(1);
SPFile file = web.GetFile(item.Url);
SPFileVersionCollection collection = file.Versions;
ArrayList idList = new ArrayList();
foreach (SPFileVersion ver in collection)
{
  idList.Add(ver.ID);
}
foreach (int verID in idList)
{
try
{
  collection.DeleteByID(verID);
}
catch (Exception ex)
{
  MessageBox.Show(ex.Message); 
}

}

Monday, June 2, 2014

Bug in SharePoint 2013 for Public Facing Sites - Popup message to Run ActiveX Controls

Recently in one of my SharePoint 2013 project which is Public Facing Site faced an issue of "The Web site wants to run the following add-on: 'Name ActiveX Control".


The SharePoint plugin that those web sites try to load is only useful for collaboration but not for public facing web sites.



Issue in Default SharePoint Javascript Files:-
The actual code will look like this in init.js file, which can be found inTemplates\Layouts\15\1033


function ProcessImn() {
if (EnsureIMNControl() && IMNControlObj.PresenceEnabled) { imnElems=document.getElementsByName("imnmark"); imnElemsCount=imnElems.length; ProcessImnMarkers(); }
}

function ProcessImnMarkers() {
for (i=0;i<imnMarkerBatchSize;++i) { if (imnCount==imnElemsCount) return; IMNRC(imnElems[imnCount].sip,imnElems[imnCount]); imnCount++; } setTimeout("ProcessImnMarkers()",imnMarkerBatchDelay);
}

Work Around Solution:-
Two ways you can go, one is

Comment all the above lines.Search for the function ProcessDefaultOnLoad() in the init.js file. Comment the ProcessImn() function. Now execute. Warning will no more display.


The other way and Preferred method will be,
Add below two Javascript Lines in your master Page,


function ProcessImn() {}
function ProcessImnMarkers() {}


Now for end user will not popup the The Web site wants to run the following add-on: 'Name ActiveX Control"





for more info:- http://support.microsoft.com/kb/931509

Monday, May 26, 2014

Determine which SharePoint Version the Site

Basically we can go with step wise as initial step looking for default css files. 
  • SharePoint 2013 will have corev15.css. 
  • SharePoint 2010 will have corev4.css
If you dont find those , please click F12 and open up the Developer tools. In that go to  Network tab and look for MicrosoftSharePointTeamServices in the response headers of the site.
  • For SharePoint 2010 sites --> MicrosoftSharePointTeamServices --> 14.0.0.6114 
  • For SharePoint 2013 sites --> MicrosoftSharePointTeamServices --> 15.0.0.4420
  • Below is detailed report for MOSS 2007

12.0.0.6535 MOSS 20071 or WSS 3.0 SP2 + December 09 cumulative Update (KB960010 + KB960011)
12.0.0.6524 MOSS 20071 or WSS 3.0 SP2 + 15th December Update (KB977027 + KB977026)
12.0.0.6520 MOSS 20071 or WSS 3.0 SP2 + October 09 cumulative Update (KB974989 + KB974988)
12.0.0.6514 MOSS 20071 or WSS 3.0 SP2 + August 09 cumulative Update (KB973400 + KB973399)
12.0.0.6510 MOSS 20071 or WSS 3.0 SP2 + June 09 cumulative Update (KB971538 + KB971537)
12.0.0.6504 MOSS 20071 or WSS 3.0 SP2 + April 09 cumulative Update (KB968850 + KB968851)
12.0.0.6421 MOSS 20071 or WSS 3.0 SP2 (KB953338 + KB953334) [Updated 1st Aug 09: SP2 download now includes the hotfix (KB971620) that corrects the activation issue more information on the Microsoft SharePoint team blog]
12.0.0.6341 MOSS 20071 or WSS 3.0 February 09 cumulative Update (KB961755 + KB961756)
12.0.0.6335 MOSS 20071 or WSS 3.0 December 08 cumulative Update (KB960010 + KB960011)
12.0.0.6331 MOSS 20071 or WSS 3.0 October 08 cumulative Update (KB957691 + KB957693,KB958567 and KB958569)
12.0.0.6327 MOSS 20071 or WSS 3.0 August 08 cumulative update (KB956056 & KB956057)
12.0.0.6318 MOSS 20071 or WSS 3.0 Infrastructure Update (KB951695 & KB951297)
12.0.0.6303 MOSS 20071 or WSS 3.0 post-SP1 hotfix (KB948945)
12.0.0.6301 MOSS 20071 or WSS 3.0 post-SP1 hotfix (KB941274)
12.0.0.6300 MOSS 20071 or WSS 3.0 post-SP1 hotfix (KB941422)
12.0.0.6219 MOSS 20071 or WSS 3.0 SP1
12.0.0.6039 MOSS 20071 or WSS 3.0 October public update
12.0.0.6036 MOSS 20071 or WSS 3.0 August 24, 07 hotfix package
12.0.0.4518 MOSS 20071 or WSS 3.0 RTM
12.0.0.4407 MOSS 20071 or WSS 3.0 Beta 2 TR
12.0.0.4017 MOSS 20071 or WSS 3.0 Beta 2
12.0.0.3111 Office 12 (PDC image - pre-beta) - This version of Office does not have a support link in the Add/Remove programs dialog box.


Will Keep posting if I find any more info on this.