Friday, April 18, 2014

Develop SharePoint webparts

Most of the times you need to  develop SharePoint webparts based on various requirements of the project by customizing your SharePoint site.
Even though there are lots of requirements and functionality can be achieved using SharePoint OOB (out of the box) features, still you might require more often than not need to write code to develop SharePoint webparts to achieve the requirements of the client.
To understand the SharePoint webpart development, in this post we will work on one basic example where you will insert the details to a SharePoint list and display those details in a gridview.
Once you complete this article, you will understand what is
  1. Scope in SharePoint,
  2. Elements.xml for deployment of SharePoint webparts,
  3. . webpart file in webparts,
  4. Object model using SPlist object for performing list operations,
  5. CAML query.


Most of the above details are important while developing a basic SharePoint development. Especially while developing the SharePoint webparts.

Webpart development:

We will use Visual studio 2012 to develop SharePoint webparts and deployed them to SharePoint 2013 environment.
To start developing webparts, open visual studio 2012
Click on [file] [New Project] ,  it will open the below figure from the SharePoint solutions  select SharePoint 2013-empty project .
Once you click ok, It will open the create project wizard where you can select or enter  the site URL from where you can deploy the SharePoint webparts as a sandboxed solution or farm solution. In this POC select deploy as a sandbox solution.
project-wizard
Click on finish button. It will create an empty project. Now its time to add web part to the project that has been created.
Right click on the project and [add] [New item..] , select web part item  and enter "Projects" in Name section and click  "Add" button. The web part item will get added to the project.
SharePoint Webpart
Once you add the SharePoint webpart it will create feature1 under features folder. Edit the feature by right clicking on the feature or select it and press F2 keyword then modify the feature name.
To change the Title and description properties double click on it. In the below figure we are mentioning Title as Projects and Description as "Add and display the Projects"  and also the scope of the web part always is at site level i.e. Referring a particular Site collection.
There are four levels of scopes in SharePoint.
1. Farm : This scope will be used to deploy the components at Farm level.
2. Web application : This scope will be used to deploy the components at web application level.
3. Site : This scope will be used to deploy the components at site collection level.
4. Web : This scope will be used to deploy the components at site level.

webpart feature

Elements.xml :

Once you add a webpart to the project it will create two files one is Elemnts.xml and other one is .webpart file. Below code snippet shows the details of elements.xml file.
Module in elements.xml file specifys where to deploy the component or arifact in SharePoint site and the list id =113, which specifies web part gallery  and URL Specifies the virtual path where the files will get deployed when you deploy the feature.
1 2 3 4 5 6 7 8
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/" >
<Module Name="Projects" List="113" Url="_catalogs/wp">
<File Path="Projects\Projects.webpart" Url="SharePoint-webpart_Projects.webpart" Type="GhostableInLibrary">
<Property Name="Group" Value="Custom" />
</File>
</Module>
</Elements>
view raw webpart-element.xml hosted with ❤ by GitHub

Please check more details about module  here.

.webpart File :

Below code snippet shows the details of .webpart file.
In the below code metadata  will have information about the webpart. Type contains the full path of the source file and importErrorMessage  used to display the message to the users where there is an error while importing the webpart and you can see the usage of resource files for multilingual support..
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
<?xml version="1.0" encoding="utf-8"?>
<webParts>
<webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
<metaData>
<type name="SharePoint_webpart.Projects.Projects, $SharePoint.Project.AssemblyFullName$" />
<importErrorMessage>$Resources:core,ImportErrorMessage;</importErrorMessage>
</metaData>
<data>
<properties>
<property name="Title" type="string">SharePoint-webpart - Projects</property>
<property name="Description" type="string">My Web Part</property>
</properties>
</data>
</webPart>
</webParts>
view raw projects.webpart.xml hosted with ❤ by GitHub
To see how the properties will work, deploy this SharePoint webpart by right clicking on the project and click on deploy, it will get deployed to the SharePoint site which you specified in the properties.
Open the SharePoint site ..
Go to [site settings] [webparts under web designer galleries] where all SharePoint webparts will be available.
To check the webpart you have deployed just now by sorting modified date field. Recently deployed web part  will show  *New symbol.
Click on Edit button against your webpart, it will show the below figure how the values of Title and Description properties you have in .webpart file showing it here.
If you want to change the values of  these properties, you simply use the Export button in the ribbon control and download it your local folder and upload it back again to change the Title and description values.
web-part-gallery
Please check here for full reference of .webpart file

Webpart class file:

The webpart class file inherits from System.Web.UI.WebControls.WebParts.webpart and which is an ASP.net class. Once you add a webpart, CreateChildControls method will get created by default. This method is very important in a webpart life cycle where different events will fire.
CreateChildControls method used to render various controls like textbox, button, gridview etc.

using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
namespace SharePoint_webpart.Projects
{
[ToolboxItemAttribute(false)]
public class Projects : WebPart
{
protected override void CreateChildControls()
{
}
}
}
view raw projects.cs hosted with ❤ by GitHub

Add List Item:

The below code snippet is used to add project details to a SharePoint list.
In the below code I have used Textbox and button controls.
If you observe the below snippet the controls are created and added in createchildcontrols method.
In the button click event we have written a simple object model to deploy the values to SharePoint list.
 
using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
namespace SharePoint_webpart.Projects
{
[ToolboxItemAttribute(false)]
public class Projects : WebPart
{
//declare all variables
TextBox txtproject;
Button btnadd;
//load all controls
protected override void CreateChildControls()
{
txtproject = new TextBox();
txtproject.ID = "txtproject";
btnadd = new Button();
btnadd.ID = "btnadd";
btnadd.Text = "Add Project";
btnadd.Click += btnadd_Click;
Controls.Add(txtproject);
Controls.Add(btnadd);
}
//Add the project to a list
void btnadd_Click(object sender, EventArgs e)
{
SPWeb web = SPContext.Current.Web;
//SPList projectsList = web.Lists["Projects"];
//use the below line code for best prectices
SPList projectsList = web.GetList("http://sharepoint-journey/sites/Apps/Lists/Projects/AllItems.aspx");
SPListItem newItem = projectsList.Items.Add();
newItem["Title"] = txtproject.Text.ToString();
newItem.Update();
txtproject.Text = string.Empty;
}
}
}
view raw complete-projects.cs hosted with ❤ by GitHub
Check the best coding practices article.
After adding the above code, build the solution and right click on the project and deploy it.
To add webpart click on Page and click on the Edit button from the ribbon control.
From the below figure click on Insert and select webpart from custom category select your webpart and click on add.
Add-webpart-to-page
Once you have added the webpart, save and publish the page.
Project Details-Add Item

Test webpart:

Create SharePoint List:

Create Projects List to store the values by clicking on site contents from recent section on the home page or the settings button on the top right of the site.
Click on add an App button and select the Custom List and enter the Name as Projects and click on create button.
Once you created the Projects list, go the webpart page enter Project name as "Project A" and click Add, you can see that item has been added to the list. See the below figure for reference.
Project Details-Added to List
So far we have developed SharePoint webpart which will used to save items in custom SharePoint list.
The next part is how to display the details which we have stored in a SharePoint list.

Display List details:

To display SharePoint list we have many ways such as using CAML query, Jquery with the help of SPservices etc.
In this post we will be using CAML query to get the list details which have been stored before.
Lets quickly see the below code snippet where we are using getdata method to get the Id and Title of projects list. We are using SPquery object to execute the CAML query.
In the below CAML query where condition doesn't have any impact, but you can learn how the Where condition will be used in CAML query.

using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Data;
namespace SharePoint_webpart.Projects
{
[ToolboxItemAttribute(false)]
public class Projects : WebPart
{
//declare all variables
TextBox txtproject;
Button btnadd;
GridView grdprojects;
// A table for layout
Table tbl;
TableRow row;
TableCell cell;
//load all controls
protected override void CreateChildControls()
{
tbl = new Table();
row = new TableRow();
cell = new TableCell();
txtproject = new TextBox();
txtproject.ID = "txtproject";
cell.Controls.Add(txtproject);
cell.Width = 10;
row.Controls.Add(cell);
btnadd = new Button();
btnadd.ID = "btnadd";
btnadd.Text = "Add Project";
btnadd.Click += btnadd_Click;
cell = new TableCell();
cell.Controls.Add(btnadd);
row.Controls.Add(cell);
tbl.Controls.Add(row);
row = new TableRow();
cell = new TableCell();
cell.ColumnSpan = 2;
grdprojects = new GridView();
grdprojects.AutoGenerateColumns = true;
grdprojects.DataSource = getdata();
grdprojects.DataBind();
cell.Controls.Add(grdprojects);
row.Controls.Add(cell);
tbl.Controls.Add(row);
Controls.Add(tbl);
}
private DataTable getdata()
{
SPWeb web = SPContext.Current.Web;
SPList projectsList = web.GetList("http://sharepoint-journey/sites/Apps/Lists/Projects/AllItems.aspx");
//In the below CAMl query i am using Where condition even though it is not applicable, so that you can always remebre the standard sysntax.
var query = "<Query>" +
"<Where>" +
"<Neq>" +
"<FieldRef Name='ID'/><Value Type='Number'>0</Value>" +
"</Neq>" +
"</Where>" +
"<OrderBy>" +
"<FieldRef Name='Title'/>" +
"</OrderBy>" +
"</Query>";
SPQuery spQuery = new SPQuery();
spQuery.ViewFields = "<FieldRef Name='Id' /><FieldRef Name='Title' />";
spQuery.Query = query;
SPListItemCollection items = projectsList.GetItems(spQuery);
DataTable dtprojects = items.GetDataTable();
return dtprojects;
}
//Add the project to a list
void btnadd_Click(object sender, EventArgs e)
{
SPWeb web = SPContext.Current.Web;
SPList projectsList = web.GetList("http://sharepoint-journey/sites/Apps/Lists/Projects/AllItems.aspx");
SPListItem newItem = projectsList.Items.Add();
newItem["Title"] = txtproject.Text.ToString();
newItem.Update();
txtproject.Text = string.Empty;
}
}
}
view raw projects.cs hosted with ❤ by GitHub
Once you complete the code, build and deploy the solution to test.

Conclusion:

In this post you have seen how to develop SharePoint webparts in SharePoint 2013 using visual studio 2012.
Which will be used to insert a list item using object model and get the list details using  CAML query and display it in a gridview.
You have also understood the importance of scope in SharePoint. Elemnets.xml and .webpart importance in development of SharePoint Web Parts.
In the next article you will get to know how to develop custom properties in a webpart and what is the importance of it.

Thursday, April 17, 2014

Custom Actions in Apps for SharePoint 2013

Introduction

Custom actions in Apps for SharePoint allow users to interact with list menu and SharePoint ribbon. You can deploy custom actions either to host web or app web. Deploying to app web will restrict the custom action just within your app. When a custom action is deployed to the host web, you can allow users to open a page in your app – in this way it is very easy to allow users navigate to your app.
For example: If you have an event management app that picks the events from the event calendar in the host web, then you could have a list menu custom action that allows users to register for the selected event by taking you directly to the event management app.
Custom actions can be either:
  • List Menu Custom Action
  • Ribbon Custom Action
In this blog post let us lets create a simple list menu custom action using Visual Studio 2012!

List Menu Custom Action Sample

Creating the List Menu Custom Action

Open Visual Studio 2012 as administrator (this is required to build apps for SharePoint)
Create a new project and select App for SharePoint 2013
Enter MyCustomAction for the project name
In the next wizard page, enter your SharePoint site Url and select SharePoint-hosted as your hosting option
Click Finish to create the project
image
Right click the app for SharePoint project and select Add | New Item
Choose Menu Item Custom Action and enter MyListMenuCA as the Name
image
Click Add to add the custom action
In the next wizard page, you can choose where to deploy your custom action along with the scope of the custom action
Choose Host Web and scope the custom action to List Instance
Choose Documents library item for which the custom action is scoped to
image
Notice that you can choose various locations where you want to scope your list menu custom action
 image
If you had chosen File Extensions, you are able to then choose the file extension type (though only 3) – pretty cool :)
image
Back to the wizard – click Next to proceed
In the next wizard page, you can choose the appropriate name for the menu item and the page (in the app) to navigate to.
Accept the defaults and click Finish to create the custom action
image
Visual Studio will add the custom action to your project
image
Press F5 to debug your app and if everything works, then you will be taken to the app directly:
image
Since our custom action is deployed to the Documents library in the host web, we have to navigate to that library to invoke the custom action
Click on the Developer Site on the top left corner – this will take you to the host web.
Navigate to Documents library and select any document in the library and click the ellipsis icon to show the list menu
Click the ellipsis icon again (yep, too many ellipsis! :) ) and there you will find your custom action at the end!
 image
Clicking on the custom action should take you the app

Writing code to get item details

What is the use of the custom if we are not able to get the details of the item from which it was invoked, right?
Let us write some code to exactly do that!

Include Query String Parameters

In order to get the item details, we need SharePoint to pass some values as query string parameters
Open Elements.xml under the custom action MyListMenuCA
We will replace the UrlAction element’s Url property to include the following:
  • Standard tokens
  • Query string parameters for:
    • List Id
    • List Item Id
Below is the modified code:
<UrlAction Url="~appWebUrl/Pages/Default.aspx?{StandardTokens}&amp;SPListItemId={ItemId}&amp;SPListId={ListId}" />
The code corresponding to the query string parameter is:
{StandardTokens}&amp;SPListItemId={ItemId}&amp;SPListId={ListId}

Display Query String Parameters

Lets replace the Default.aspx PlaceHolderMain content place holder with the following code:
<asp:Content ContentPlaceHolderID="PlaceHolderMain" runat="server">

    <div>
        <ul id="queryStringParams" />
    </div>

    <div>
        <input type="button" id="btnItemDetails" 
            onclick="getItemDetails()" value="Get Item Details" />
    </div>  

    <div>
        <p id="message">            
            No item selected.
        </p>
    </div>

</asp:Content>
Open App.js in the Scripts folder:
Add the following variables at the top:
var appWebContext;
var hostWebContext;

var web;
var hostWeb;

var selList;
var selListItem;
Replace the document.ready function with the following:
$(document).ready(function () {

    var params = $.getUrlVars();

    if (!$.getUrlVar("SPListItemId")) {
        $("#btnItemDetails").prop("disabled", true);
    }

    var paramsHTML = "";   

    for (var i = 0; i < params.length; i = i + 1) {
        params[i] = decodeURIComponent(params[i]);
        paramsHTML += "<li>" + params[i] + " ==> "
            + decodeURIComponent($.getUrlVar(params[i])) + "</li>";
    }

    document.getElementById("queryStringParams").innerHTML = paramsHTML;

});
The code above gets the query string parameters and builds a string inserts that text into the Html element queryStringParams
Now add the code query the query string(thanks to jQuery Howto blog for the code):
$.extend({
    getUrlVars: function () {
        var vars = [], hash;
        var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
        for (var i = 0; i < hashes.length; i++) {
            hash = hashes[i].split('=');
            vars.push(hash[0]);
            vars[hash[0]] = hash[1];
        }
        return vars;
    },
    getUrlVar: function (name) {
        return $.getUrlVars()[name];
    }
});
If you debug the app now, you will see the query strings passed:
image

Get Item Details

Let us now implement the Get Item Details method to query the selected item
Remember, custom action is deployed to host web and the selected item is actually in a document library in the host web
So, we have to query the host web document library to get the item details
function getItemDetails() {

    appWebContext = new SP.ClientContext.get_current();

    hostWebContext = new SP.AppContextSite(appWebContext, decodeURIComponent($.getUrlVar("SPHostUrl")));

    selList = hostWebContext.get_web().get_lists().getById(decodeURIComponent($.getUrlVar("SPListId")));

    selListItem = selList.getItemById(decodeURIComponent($.getUrlVar("SPListItemId")));

    appWebContext.load(selList);

    appWebContext.load(selListItem, 'Title');

    appWebContext.executeQueryAsync(onGetListItemSucceeded, onFail);
}

function onGetListItemSucceeded(sender, args) {

    $("#message").text("Selected Item Title = " + selListItem.get_item('Title'));
}
function onFail(sender, args) {
    alert('Failed to execute the request. Error:' + args.get_message());
}
How do we query the host web? – the code in Red shows how to query the host web – get the current context (app) and we will create a new app context for the host web by passing the site Url, which is the SPHostUrl in the query string. Once we have the host web context, we can then get the associated list by list Id and then the item by Id. But you still have to execute the original appWebContext as your code is executed within your app.
Lets see what we get if we debug the app, invoke the custom action and press Get Item Details button:
image
Oops! – That is not good – what is wrong?
As the item is in a library in the host web, the app has to have the required permissions to access the specified library to query the item!

Configure App Permissions

We haven’t configured any permissions yet.
Open AppManifest.xml and navigate to Permissions tab
Add the following permission to read a list:
image
We have requested permission to read a list but we haven’t specified which list. The list will be requested during the installation.
Lets debug the app:
You are now requested to choose from which list you want the app to have read permission
Select Documents as we have deployed our custom action to the Documents library and click Trust It
image
Now invoke the custom action and press Get Item Details button:
You should see the item title being updated below the button
image


Building apps for SharePoint with MVC – Part 2

In my previous post we built a provider-hosted app with MVC to display items from a Product list. We also used bootstrap to quickly style our app web page.
Lets take our sample to the next level – let us add the UI to add a new product item.

‘Add New’ Modal Dialog

Open our sample and navigate to Home\Index view.
Add the following code after the table:
<!-- Button trigger modal -->
<a data-toggle="modal" href="#myModal" class="btn btn-primary btn-large">Add Product</a>

<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">

            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                <h4 class="modal-title">New Product</h4>
            </div>

            <div class="modal-body">
                <form class="form-horizontal well">
                    <fieldset>
                        <div class="form-group">
                            <label for="productTitle">Title</label>
                            <input type="text" class="form-control" id="productTitle" placeholder="Enter product title">
                        </div>
                        <div class="form-group">
                            <label for="productDescription">Description</label>
                            <input type="text" class="form-control" id="productDescription" placeholder="Enter product description">
                        </div>
                        <div class="form-group">
                            <label for="productPrice">Price</label>
                            <input type="text" class="form-control" id="productPrice" placeholder="Enter product price">
                        </div>
                    </fieldset>
                </form>
            </div>

            <div class="modal-footer">                            
                <button id="btnClose" type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                <button id="btnSaveProduct" type="button" class="btn btn-primary">Save</button>
            </div>

        </div><!-- /.modal-content -->
    </div><!-- /.modal-dialog -->
</div><!-- /.modal -->
The code adds a modal form using bootstrap – clicking the button will open a modal dialog form with the required labels and text fields
Now lets add the JS code to call the required action method to add a new product.
You can include your own .js file, but to keep things simple for the sample, let us add the JS code in the MVC ‘scripts’ section.
Add the following code at the end of the file:
@section scripts {
    <script type="text/javascript">


    $(document).ready(function () {

        $("#btnSaveProduct").click(function (e) {
            e.preventDefault();

            var spHostUrl = getSPHostUrlFromQueryString(window.location.search);

            var urlAddProduct = "/Home/AddProduct?SPHostUrl=" + spHostUrl;

            $.post(urlAddProduct,
                    {
                        title: $("#productTitle").val(),
                        description: $("#productDescription").val(),
                        price: $("#productPrice").val(),
                    }).done(function () {
                        $("#myModal").modal('hide');
                    })
                    .fail(function () {
                        alert("Failed to add the new product!");
                    });
        });

        // Gets SPHostUrl from the given query string.
        function getSPHostUrlFromQueryString(queryString) {
            if (queryString) {
                if (queryString[0] === "?") {
                    queryString = queryString.substring(1);
                }

                var keyValuePairArray = queryString.split("&");

                for (var i = 0; i < keyValuePairArray.length; i++) {
                    var currentKeyValuePair = keyValuePairArray[i].split("=");

                    if (currentKeyValuePair.length > 1 && currentKeyValuePair[0] == "SPHostUrl") {
                        return currentKeyValuePair[1];
                    }
                }
            }

            return null;
        }

    });

    </script>
}
Things to note here:
  • We append the action URL with SPHostUrl. This is very important as the remote web application needs at least the SharePoint host web URL to create the context.
  • SharePointContextFilter class will take care of creating the context as long as the URL as SPHostUrl, so you don’t have to worry about creating the context.
  • We get the SPHostUrl from the query string. Since your app was initially redirected from SharePoint, SharePoint adds the standard tokens which includes SPHostUrl.
    • You can find the method in Scripts\spcontext.js
  • We are still in the Home\Index view and haven’t created a separate view, instead just use a modal form to add a new product.

Home Controller – AddProduct Action Method

[HttpPost]
[SharePointContextFilter]
public ActionResult AddProduct(string title,string description,string price)
{
    HttpStatusCodeResult httpCode = new HttpStatusCodeResult(HttpStatusCode.MethodNotAllowed);

    var spContext = SharePointContextProvider.Current.GetSharePointContext(HttpContext);

    Product newProduct = new Product();
    newProduct.Title = title;
    newProduct.Description = description;
    newProduct.Price = price;

    if (SharePointService.AddProduct(spContext, newProduct))
    {
        httpCode = new HttpStatusCodeResult(HttpStatusCode.Created);
    }

    return httpCode;
}
As you can see, we add the SharePointContextFilter attribute to the action. This will ensure a proper SharePoint context is created.
For the sake of this sample, we just return HTTP status code.

SharePoint Service – Add Product

Finally we add the add product method to SharePointService that adds the new product to Products list:
public static bool AddProduct(SharePointContext spContext, Product product)
{
    using (var clientContext = spContext.CreateUserClientContextForSPAppWeb())
    {
        if (clientContext != null)
        {
            try
            {
                List lstProducts = clientContext.Web.Lists.GetByTitle("Products");

                ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation();
                ListItem newProduct = lstProducts.AddItem(itemCreateInfo);
                newProduct["Title"] = product.Title;
                newProduct["ProductDescription"] = product.Description;
                newProduct["Price"] = product.Price;
                newProduct.Update();

                clientContext.ExecuteQuery();

                return true;
            }
            catch (ServerException ex)
            {
                return false;
            }
        }
    }

    return false;
}

Debug the app

Click the Add Product button at the bottom of the page. You will get a modal dialog. Fill out the new product information and click Save:
image
Refresh the page to see the new product added!
image

Deploying Root Items in apps for SharePoint

SharePoint development has never been easier, thanks to Visual Studio SharePoint Tools. If you remember the Visual Studio Extensions for Windows SharePoint Services (VSeWSS), you will know what I mean.
To deploy specific files (like pages, scripts etc.,) in SharePoint from your app or solution, you have to know about Modules in SharePoint which groups items into folders and specify where each item in the module gets deployed.
If you create a new SharePoint-hosted app, you will see the following modules added by default by Visual Studio:
  • Content
    • Items are deployed to: {site}/Content/
  • Images
    • Items are deployed to: {site}/Images
  • Pages
    • Items are deployed to: {site}/Pages
  • Scripts
    • Items are deployed to: {site}/Scripts
SharePoint-hosted app
so what about ‘real folders’ and files in the root of your project?

Root folders and files

You can now add root folders and items to your app for SharePoint project and they will be deployed to the root of your site automagically!
So, you can have something like this:
Root Folders
As you can see, we have added folders instead of modules – css, HTML and js
They will be deployed to – {site}/css , {site}/HTML , {site}/js – respectively, just like in Modules, but less work!
You don’t have to worry about modules anymore! Need to deploy some files to SharePoint? Sure, just add them to the root of your project and reference them in other places! Visual Studio will take care of deploying them to SharePoint!
If you don’t want any file to deployed, such as a ReadMe file, you can do so by selecting NoDeployment as the Deployment Type in the property grid:
Root file deployment type
One thing to remember is that the root item deployment are only supported in apps for SharePoint.

Building apps for SharePoint with MVC--Part 1

One of the cool features app for SharePoint developers get in Visual Studio 2013 is the ability to create MVC web application projects as the remote web application for provider-hosted and autohosted apps.
Visual Studio 2013 adds a ton of features to web development stack that includes new web project experience, MVC 5, etc. You get all these goodness in apps for SharePoint too, as creating an app with MVC will automatically create a MVC 5 web application that includes all the great new features!
So, lets build a simple app with MVC!

Default MVC Template

If you are not familiar with the MVC template generated out of the box, I would highly recommend reading Introducing MVC Support for apps for SharePoint.
Fire up Visual Studio 2013 and create a new provider-hosted app for SharePoint project with MVC as the remote web application project authenticating with Windows Azure Access Control service.
image

image
The default out of the box MVC project has all the required SharePoint assemblies, references and sample code for you to get started.
Debug the app and you will have a nice looking home page with some useful links for app for SharePoint development.
image

Sample Code

The sample code available in Home Controller default view gets the current user name from SharePoint:
[SharePointContextFilter]
public ActionResult Index()
{
    User spUser = null;

    var spContext = SharePointContextProvider.Current.GetSharePointContext(HttpContext);

    using (var clientContext = spContext.CreateUserClientContextForSPHost())
    {
        if (clientContext != null)
        {
            spUser = clientContext.Web.CurrentUser;

            clientContext.Load(spUser, user => user.Title);

            clientContext.ExecuteQuery();

            ViewBag.UserName = spUser.Title;
        }
    }

    return View();
}
The key thing to note here are the two helper classes:
  • The SharePoint Context Filter attribute performs additional processing to get the standard information when redirected from SharePoint to your remote web application, such as Host Web Url.
    It also determines whether the app needs to be redirected to SharePoint for the user to sign in (in case of bookmarks).
    You can apply this filter either to the controller or to a view.
  • SharePoint Context Provider classes encapsulate all the information from SharePoint so that you can easily create specific contexts for the app web and host web right away and communicate with SharePoint.

Add a Products list

For this sample, let us add a simple list and query list items.
Let us now add a custom list called Products to our app for SharePoint project with the following columns.
image
To make it easy, I usually add default items to the list in the list instance elements file which will add the items you define when the list is created:
image

SharePointService – Get User Name

Back in the MVC project, let us add a class SharePointService to abstract the SharePoint calls and copy the sample code to get the user name into the following method:
public static class SharePointService
{
    public static string GetUserName(SharePointContext spContext)
    {
        string strUserName = null;

        User spUser = null;            

        using (var clientContext = spContext.CreateUserClientContextForSPHost())
        {
            if (clientContext != null)
            {
                spUser = clientContext.Web.CurrentUser;

                clientContext.Load(spUser, user => user.Title);

                clientContext.ExecuteQuery();

                strUserName = spUser.Title;
            }
        }

        return strUserName;
    }       
}

MVC Model – Products

To interact with products, let us create a Product model under the Models folder:
image
public class Product
{
    public string Title { get; set; }

    public string Description { get; set; }

    public string Price { get; set; }
}

SharePointService – Get Products

Now that we have the model ready, let us add the method to get all the products in our SharePointService class:
public static List<Product> GetProducts(SharePointContext spContext, CamlQuery camlQuery)
{
    List<Product> products = new List<Product>();

    using (var clientContext = spContext.CreateUserClientContextForSPAppWeb())
    {
        if (clientContext != null)
        {
            List lstProducts = clientContext.Web.Lists.GetByTitle("Products");

            ListItemCollection lstProductItems = lstProducts.GetItems(camlQuery);

            clientContext.Load(lstProductItems);

            clientContext.ExecuteQuery();

            if (lstProductItems != null)
            {
                foreach (var lstProductItem in lstProductItems)
                {
                    products.Add(
                        new Product
                        {
                            Title = lstProductItem["Title"].ToString(),
                            Description = lstProductItem["ProductDescription"].ToString(),
                            Price = lstProductItem["Price"].ToString()
                        }); 
                }
            }
        }
    }

    return products;
}
The code is nothing different than any CSOM code. The method accepts the context and a CAML query object and executes the query on the Products list to get the required items

Home Controller – Index View Code

Now that we have the required code to talk back to SharePoint, we can modify the default view code to call the same:
[SharePointContextFilter]
public ActionResult Index()
{
    var spContext = SharePointContextProvider.Current.GetSharePointContext(HttpContext);

    ViewBag.Username = SharePointService.GetUserName(spContext);

    CamlQuery queryProducts = new CamlQuery();
    queryProducts.ViewXml = @"<View><ViewFields><FieldRef Name='Title'/>
                                <FieldRef Name='ProductDescription'/>
                                <FieldRef Name='Price'/></ViewFields></View>";

    List<Product> products = SharePointService.GetProducts(spContext, queryProducts);

    return View(products);
}
As you can see, we return the list of all products back to the view

Home\Index View

The only thing left to modify now is the view code.
Navigate to the Home\Index view and replace <div class=”row”> section with the following code:
<div class="row">

    <div class="col-lg-12">
        <div class="span8">
    
            <p class="lead"><u>Product List</u></p>

            <table class="table table-striped">
                <thead>
                    <tr>
                        <th>Title</th>
                        <th>Description</th>
                        <th>Price</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (SharePointAppSampleWeb.Models.Product objProduct in Model)
                    {
                        <tr>
                            <td>@objProduct.Title</td>
                            <td>@objProduct.Description</td>
                            <td>@objProduct.Price</td>
                        </tr>
                    }
                </tbody>
            </table>
        </div>
    </div>
</div>
Cool thing to note here is that MVC 5 uses Bootstrap out of the box.
If you not familiar with bootstrap, I would highly recommend you to get familiar as it is the best CSS/JS library you will ever learn to quickly build what you want!
In the code above, we build a simple table by enumerating the products object. The table itself uses bootstrap CSS styles to render the table.

Debug App

So, lets debug the app to see how it looks!
image
Woah! Thats a nice looking table! Bootstrap rocks!
And if you haven’t noticed, you app is also responsive.You get it for free with Bootstrap!
image