How to Debug your SharePoint App SharePoint 2013


In SharePoint 2013 app development, you need to run the app from visual studio to debug. However as you debug and you need to make some changes in html or JavaScript, you might wonder that you need to stop debugging, make changes and redeploy the app again. But there’s simplest solution exists.

Unproductive Approach

You might be aware of the following steps which might take long time to debug and make changes:
  1. Run the app from Visual Studio in debug mode (with F5).
  2. Debug your JavaScript and you’ve found you need to make changes
  3. Stop the debug and make changes
  4. Rerun the app from Visual Studio with F5
But there’s simplest approach exists for debugging as described next.

Productive Approach

You may not know that you don’t need to stop debugging to make changes. You can make changes while the app is running and then refresh the page in the browser. You will get your changes on refreshing/reloading the page. So the new steps are:
  1. Run the app from Visual Studio in debug mode (with F5).
  2. Debug your javascript and you’ve found you need to make changes
  3. Make those changes in Visual Studio without stopping the app.
  4. Refresh the page in Browser, you will get the changes (HTML, JavaScript) immediately.

Conclusion

Using the second (productive approach) approach, you can develop and debug faster. However, if you make any setting changes like feature changes or appmanifest changes, you need to stop debugging and rerun again.

How to Use CAML into REST request in SharePoint 2013


You might wonder how to use CAML query in your SharePoint 2013 REST endpoints. Basically you can’t pass CAML into REST request (at least till date, there’s so documented approach published). However, REST by itself provides the querying feature which somehow covers almost all CAML querying features. I’ll try to explain today how you can convert your CAML into REST request.

Generate REST Request Url

First of all let’s play with a tool called LINQPad that will be used for REST request generation later from CAML.Let’s describe the process step by step.
  1. Download LINQPad: The tool that I’m going to use for generating REST request url can be downloaded from LINQPad site. So please download the tool and run it.
  2. Add Connection Provider: Once you run the tool click ‘Add Connection’ and then select ‘WCF Data Services (OData)’ data context provider as shown below:
    image
    Figure 1: Add WCF Data Connection 
  3. Connect to SharePoint Server: In the connection page, select the url as http://server/_vti_bin/ListData.svc as shown below:
    image
    Figure 2: ListData WCF Connection 
  4. Built-in Query Option: Use built-in template for querying as shown below. Right click on your list/library and use any built-in template you want.
    image
    Figure 3: Use built-in template for generating query 
  5. Generate Query: Once you finish the query, execute it and click the ‘Request Log’ button to see the REST request generated as shown below:
     image
    Figure 4: C# query and REST request 
For details REST operator you can use for SharePoint 2013 REST endpoint can be found at MSDN link under “Table 3. OData query operators”. For licensed version, LINQPad provides intellisense which really exciting feature.

Examples of C# query and corresponding REST URL

I’ve provided few basic examples of using the LINQPad tool to generate queries. For this example, let’s consider we have a product list with the following fields:
image
Figure 5: Sample product list
The following examples explains the C# query and it’s corresponding REST Url:
  • Select all products created on 10-Oct-2012
    C# Qeury
    Product.Where (p => p.Created.Value.Day==10 & p.Created.Value.Month==10 & p.Created.Value.Year==2012) 
    ListData Urlhttp://server/_vti_bin/ListData.svc/Product()?$filter=((day(Created) eq 10) and (month(Created) eq 10)) and (year(Created) eq 2012)
    REST URLhttp://server/_api/web/lists/getbytitle(‘Product’)?$filter=((day(Created) eq 10) and (month(Created) eq 10)) and (year(Created) eq 2012)
      So the filter is “$filter=((day(Created) eq 10) and (month(Created) eq 10)) and (year(Created) eq 2012)” 
    As shown above two examples, you can find out more by yourself by using the LinqPad and the MSDN function references.

     

    Convert CAML to REST Url

    Now let’s consider you have an CAML XML as shown below which returns all items from a list whose title contains ‘sharepoint’ and takes first 10 items.
    <Where> 
       <Contains> 
          <FieldRef Name='Title' /> 
          <Value Type='Text'>sharepoint</Value> 
       </Contains> 
    </Where> 
    <QueryOptions> 
       <RowLimit>10</RowLimit> 
    </QueryOptions>
    Now using LINQPad, we can convert the CAML to REST url as described below:
    image
    So the final REST Url will be http://server/_vti_bin/ListData.svc/Product()?$filter=indexof(tolower(ProductName),'sharepoint') ne -1&$top=10

     

    Conclusion

    Using a combination of LINQPad, OData query operators at MSDN link and CAML query at your hand, you can generate proper REST URL to be used. So if you have a CAML query at your hand, with a little time investment you can generate corresponding REST URL with filters and select parameters.

    How to Send Notification on Item Approved/Rejected (when Content Approval Status is changed) in SharePoint 2010


    In SharePoint 2010 new improvements are made for better event receiving management. Few new event handlers are added for site, web, list, listitems etc. However, One thing that I think badly needed was the content approval events  for list items.

    Nowadays content approval has become an integral part of content management system. Requirements has come up to do more work on content approval/reject. But unfortunately, SharePoint list/library doesn’t have events like ContentApproved, ContentRejected, ContentRequestedForReview so that user can tap the events to do their own work on content approval status changes. So it seems we need to do a lot of works manually to send notifications on content approval status changes.



    Problem: Approving Status change events Missing

    One of my client wanted to get notification on the following scenarios:

    1. On Item Add/Update: If a user edit an item and item goes to pending status as the item needs approval, the approving teams need to be notified that an item is waiting for their approval.

    2. On Item Approved: If the approving team approve the item,the user who added/updated the item needs to be notified.

    3. On Item rejected: If the approving team reject the item, the user who added/updated the item needs to be notified with reasons why the item rejected.

    But the SharePoint Object Model doesn’t have the extensibility at this point where approving status changes.

    Why Approval Status change event missing?

    The best solution would be if SharePoint team would provide us with out-of-box events for content approval. In that case, two events would be suffice. The events might be : ContentApprovingStatusChanging and ContentApprovingStatusChanged and the event argument’s AfterProperties and BeforeProperties values could be filled with the the old value and new value of Content Approving Status field value. However, one may argue that ItemAdded/ItemUpdate events are similar like Content Approval events. So when user add/edit an item and as part of the add/edit if approval status field get updated then which events to fire? ItemAdded/ItemUpdate or content approval events. Hmm.. maybe there’s complexities with the new content approval events and SharePoint team has not added the new content approval events.



    Resolution: Use ItemAdded, ItemUpdating and ItemUpdated events to keep track of approval status changing

    So consider now the problem we’re going to talk about. We need a notification system where we need to send notification to the approver or user (who is waiting for approval) on approval status change. We’ll develop a list item event receiver for ItemAdded and ItemUpdated events. When a new item will be added it’s easy to identify item status and if the status is pending then we can send notification to all people in the approving team. But when an Item is updated, you need to keep track of if the Approving status field value is changed, if so then u need to send notification. However, you can only get the old approval status field value in ItemUpdating event, but you don’t want to send notification in ItemUpdating. So it’s safe to send notification in ItemUdated event but in ItemUpdated event you’ll not get the old value. You can access the old value in ItemUpdating. So here’s the deal:

    Create a new field say OldStatus in the list. This field will be used to keep track of if the approval status field value has been changed.
    In ItemUpdating event, set the current approval status (before updating) to OldStutus field.
    In ItemUpdated, compare the current status to OldStatus field value and if they are not same then it’s for sure that the approval status has been changed. So send notification.


    So let’s go with the steps. First we need an List Event Receiver that will listen three events of the list: ItemAdded, ItemUpating and ItemUpdated. You need to send notification on two events: ItemAdded and ItemUpdated. However, we need to hook the event ItemUpdating to know whether the approval status is going to be changed

    Create a List Event Receiver to send notification

    Send notification on Item Added
    On Item added event, check if the item status is pending. If so then send notification. The following code snippet may give you the gist.

    public override void ItemAdded(SPItemEventProperties properties)
    {
        const string approvalStatusFieldInternalName = "_ModerationStatus";

        var list = properties.List;
        var approvalStatuField = list.Fields.GetFieldByInternalName(approvalStatusFieldInternalName);
        var approvalStatusFieldValue = properties.ListItem[approvalStatuField.Id];
        var approvalStatus = (approvalStatusFieldValue == null) ? string.Empty :
                                approvalStatusFieldValue.ToString();
        if (approvalStatus == "Pending")
        {
            //SendNotification()
        }
    }
    Keep track of the approval status field value (before updated) on Item Updating event
    I’m assuming that you have a field OldStatus where I’ll keep the approval status field value which is going to be changed. I’ll explain later in this post how to automatically add the field in list. But for now just take for granted that you have a field OldStatus in your list of type string. The following code show how to keep the approval status (before update) value in OldStatus field in ItemUpdating Event.

    public override void ItemUpdating(SPItemEventProperties properties)
    {
        const string approvalStatusFieldInternalName = "_ModerationStatus";

        var list = properties.List;
        var approvalStatuField = list.Fields.GetFieldByInternalName(approvalStatusFieldInternalName);
        var approvalStatusFieldValue = properties.ListItem[approvalStatuField.Id];
        var approvalStatusValue = (approvalStatusFieldValue == null) ? string.Empty :
                    approvalStatusFieldValue.ToString();

        if (string.IsNullOrEmpty(approvalStatusValue)) return;

        EventFiringEnabled = false;
        properties.ListItem["OldStatus"] = approvalStatusValue;
        properties.ListItem.SystemUpdate(false);
        EventFiringEnabled = true;
    }
    Check the OldStatus field value and current approval status value to know if the approval status changed.
    Item updated is fried once the update is done. So we’ll get the updated value of Approval Status. But fortunately, we have kept the old value of Approval Status field in OldStatus field during ItemUpdating event as shown in step 2.

    public override void ItemUpdated(SPItemEventProperties properties)
    {
        const string approvalStatusFieldInternalName = "_ModerationStatus";
        var list = properties.List;
        

        var approvalStatusField = list.Fields.GetFieldByInternalName(approvalStatusFieldInternalName);
        var currentStatuFieldValue = properties.ListItem[approvalStatusField.Id];
        var currentStatus = (currentStatuFieldValue == null) ? string.Empty : 
                            currentStatuFieldValue.ToString();

        var oldStatusFieldValue = properties.ListItem["OldStatus"];
        var oldStatus = (oldStatusFieldValue == null) ? string.Empty : oldStatusFieldValue.ToString();

        if (string.IsNullOrEmpty(oldStatus) && oldStatus != currentStatus)
        {
            //SendNotification();
        }
    }


    Create a feature receiver to attached List Event Receiver and to create field OldStatus

    Finally We need an feature receiver (not list event receiver) which will do two works: Attached our list event receiver to a list and create a field OldStatus in the list.

    FeatureActivating Event
    In FeatureActivating you need to check first if the event is already registered. If not registered then register the event. Also make sure the list has OldStatus field. In the code below, listNeedsToAttachedNotitificationReceivers is array of list names which needs to attach the event receivers.

    public override void FeatureActivated(SPFeatureReceiverProperties properties)
    {
        string[] listNeedsToAttachedNotitificationReceivers = { "Product", "Order" };
        var myAssemblyName = "MyProject.SharePoint";

        foreach (var listName in listNeedsToAttachedNotitificationReceivers)
        {
            var web = properties.Feature.Parent as SPWeb;
            var list = web.Lists[listName];
            SPEventReceiverDefinitionCollection spEventReceiverDefinitionCollection = list.EventReceivers;
            if (!IsEventReceiverAlreadyAttached(spEventReceiverDefinitionCollection, myAssemblyName))
            {
                //Attach three ItemAdded, ItemUpdating and itemUpdated event receivers
                SPEventReceiverType eventReceiverType = SPEventReceiverType.ItemAdded;
                spEventReceiverDefinitionCollection.Add(eventReceiverType, 
                    Assembly.GetExecutingAssembly().FullName, 
                    "MyProject.SharePoint.Receivers.ListItem.ContentApprovalEventHandler");
                eventReceiverType = SPEventReceiverType.ItemUpdated;
                spEventReceiverDefinitionCollection.Add(eventReceiverType, 
                    Assembly.GetExecutingAssembly().FullName, 
                    "MyProject.SharePoint.Receivers.ListItem.ContentApprovalEventHandler");
                eventReceiverType = SPEventReceiverType.ItemUpdating;
                spEventReceiverDefinitionCollection.Add(eventReceiverType, 
                    Assembly.GetExecutingAssembly().FullName, 
                    "MyProject.SharePoint.Receivers.ListItem.ContentApprovalEventHandler");
                list.Update();
            }
            EnusureOldStatusFieldExists(list);
        }
    }

    private static bool IsEventReceiverAlreadyAttached(SPEventReceiverDefinitionCollection spEventReceiverDefinitionCollection, string myAssemblyName)
    {
        bool eventReceiverAttached = false;
        for (int i = 0; i < spEventReceiverDefinitionCollection.Count; i++)
        {
            if (spEventReceiverDefinitionCollection[i].Assembly.Contains(myAssemblyName))
            {
                eventReceiverAttached = true;
                break;
            }
        }
        return eventReceiverAttached;
    }

    private static void EnusureOldStatusFieldExists(SPList list)
    {
        var field = list.Fields.TryGetFieldByStaticName("OldStatus");
        if (field == null)
        {
            list.Fields.Add("OldStatus", SPFieldType.Text, false);
            list.Update();
        }
    }
    Feature Deactivating Event
    In feature deactivating event, unregister the list event receivers. If you want you can delete the OldStatus field. However I have not deleted the field in the code below:

    public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
    {
        string[] listNeedsToAttachedNotitificationReceivers = { "Product", "Order" };
        var myAssemblyName = "MyProject.SharePoint";


        foreach (var listName in listNeedsToAttachedNotitificationReceivers)
        {
            var receiversToRemove = new List<Guid>();
            var web = properties.Feature.Parent as SPWeb;
            var list = web.Lists[listName];
            SPEventReceiverDefinitionCollection spEventReceiverDefinitionCollection = list.EventReceivers;
            for (int i = 0; i < spEventReceiverDefinitionCollection.Count; i++)
            {
                if (spEventReceiverDefinitionCollection[i].Assembly.Contains(myAssemblyName))
                {
                    receiversToRemove.Add(spEventReceiverDefinitionCollection[i].Id);
                }
            }
            if (receiversToRemove.Count > 0)
            {
                foreach (var guid in receiversToRemove)
                {
                    list.EventReceivers[guid].Delete();

                }
                list.Update();
            }
        }
    }
    How it works all together?

    It’s a bit complex huh? oK, let’s me explain how it works.

    The feature receiver needs to be activated first. The feature receiver attached the event receiver to list and create a string field OldStatus in the list.
    Next if an item is added to the list, the listItem event gets fired and if the item status is pending (means needs approval) then send notification.
    If an existing item is edited and saved then ItemUpdating event is fired. This is the event where the item is not yet saved. So I have put the current approval status in the OldStatus field. In ItemUpated event I have compared the OldStatus and current status field value. If the valued doesn’t match then the approval status is changed and we need to send the notification.

    PS: Some body tell me, you could use bellow code to instead my code is a good idea, thanks!
    to implement SPListItem.ModerationInformation.Status 
    instead of list.Fields.GetFieldByInternalName(approvalStatu
    sFieldInternalName)
    was a better option

    15 new things in SharePoint 2013

    Here are with new SharePoint 2013. With this edition comes lots of fun and also up to some level disappointment. Well, there are more fun than disappointment hence a good news.
    First let us see what all new features of SharePoint 2013 and what all product family now we have.

    First SharePoint 2013 is of course a next version of currently successfully running SharePoint 2010.

    Just like SharePoint Foundation 2010 we also have SharePoint 2013 foundation which is again a free utility that can be downloaded if you have Windows Server 2008 R2 with SP1 or new Windows Server 2012.

    we also have licensed SharePoint 2013 on premise version or the cloud version which is in office 365.

    Covering everything about SharePoint 2013 would be very difficult in a single post. So we will divide the posts and will post them as separate posts.

    It would only run on 64 bit machines and will require SQL Server 2008 R2 with SP1 or new SQL Server 2012.

    Ideal RAM should be between 8 GB to 24 GB. (making hardware more expensive with each iteration)

    Plus Microsoft has come up with new Visual Studio 2012 which is tightly integrated with SharePoint 2013. Visual Studio 2012 has a lot of new features eases the SharePoint 2013 development.

    Of course we now also have SharePoint Designer 2013 as well as Office 2013 products.
    So let's dive into the new features that has been introduced or enhanced from the previous version.

    1) Everything is App

    Now we need to think of almost everything as an App. Lists, Libraries, Calendar and even sites are apps. You can create an app and then publishes to the corporate app web application or to the Microsoft Store. Remember that when you create an app, you will work with client object model and not server object model. You can use ECAM script, HTML and jQuery to interact with SharePoint 2013. you can options to host your app either in SharePoint itself or on the cloud - provider hosted.

    The advantage is Microsoft is going to have a dedicated store for SharePoint where developers from all around the world would be publishing their apps for SharePoint which then can be consumed by other developers based on contract/license.

    Company developed apps can be hosted in internal app catelog. They enable you to use cross-platform standards, including HTML, REST, OData, JavaScript, and OAuth.

    We already have few apps ready to go for SharePoint 2013 and here they are.

    http://office.microsoft.com/en-us/store/apps-for-sharepoint-FX102804987.aspx

    2) Create / Edit Master Pages

    This is one of the biggest improvements over the last version.

    You can simply create an HTML page with CSS and images and then convert this HTML page into the master page. Does that really make you read twice? Yes, you're right. We can now convert HTML into the fully functional master page. you also get a preview of new master page before applying.

    3) Image duplicity

    You can have all your images in a site and then can define the variants of those images that you would like to use. You can have one single image and can use this image in different way like with different height, width and even by cropping an image.

    4) Windows 8 Style
    You feel like you are using Windows 8 UI metro look as we have now tiles at most of the places.

    5) Contemporary view for Mobile

    We now have new contemporary view for mobile. This view is available in HTML 5 to those who uses Windows Phone 7.5 or above and IE 9 and above, iPhone 4 or above, Safari 4 or above and Android 4 or above.

    We can also have full desktop view of SharePoint in smart phones.

    6) Drag and Drop to library

    Now we can upload the documents using drag and drop from the desktop. Files will be uploaded to the document library showing the progress bar.

    7) New context menus

    We now have more clear context menus for list items and documents.

    8) Share the documents

    Now we can select document and then share it with specific person / user with personalized message. After this email will be sent to the user so that user can access the document.

    9) Social experience has improved

    Now you can follow a document, list item and also users, posts etc. You can do a micro blogging.

    There is a new community site available where you can define you ideas, team, contributors and can also give them ranks / raputations based on the answers that they give when someone post a question. You can create badges.

    10) Preiew of Documents

    Now in document library when you hove the mouse over the document, we get to see the preview of that document right there.

    11) SkyDrive integration

    You can synchronize your contents to your desktop with the SkyDrive.

    12) BCS enhancements

    Now it also suports oData. automatic generation via Visual Studio.

    13) create an app for Office 2013

    We can create an app specially for Office 2013 so that users using office 2013 can interact with SharePoint 2013 right from office. We can use new development tool called "Napa" along with Visual Studio 2012.

    14) App event handlers and remote event handlers

    apps have their own events that we can handle like when app is installed or deleted. Remote event handlers can work with the remote components of the app for SharePoint.

    15) Translation service, PowerPoint automation service, enhanced excel service and enhanced access services.

    With new PowerPoint automation service you can now convert ppt or pptx files to PDF and other open XML formats.

    Translation Service is a new service application in SharePoint 2013 that provides translation of files and sites. When the Translation Service application processes a translation request, it forwards the request to a cloud-hosted machine translation service, where the actual translation work is performed.

    The Machine Translation Service application processes translation requests asynchronously and synchronously. Asynchronous translation requests are processed when the translation timer job executes. The default interval of the translation timer job is 15 minutes; you can manage this setting in Central Administration or by using Windows PowerShell

    There is a lot of things that can be talked about SharePoint 2013. We will cover them as an when we come across to them and share it.