MVC4 is the latest edition of the MVC framework available in Visual
Studio 2012 that implements the MVC model and is ideally suited for
developing SharePoint apps with C# and CSOM. When you develop a
SharePoint 2013 app by using MVC4, you build models, controllers, and
views, not web forms. Visual Studio 2012 helps you with the process by
providing tools, designers, and wizards that support the MVC4
framework. If you are interested in creating
SharePoint apps based on the MVC4 framework, you’ll need to do some
work to swap out the web forms project for an MVC4 project.
To get started, first create a provider-hosted or autohosted app. When the new remote web is created, open the associated web.config file and copy the settings for the ClientId and ClientSecret
entries. You will need to transfer these settings to the new MVC4
remote web. After you have copied the settings, delete the default web
project. Then, you can add a new MVC4 project to the solution. In the
New ASP.NET MVC 4 Project Wizard, select the Internet Application template, as shown in Figure 3.
After the new web project is created, you must associate it with the SharePoint app by setting the Web
Project property in the SharePoint app project. This property contains
a drop-down list of the web projects in the solution. Figure 4 shows the property.
After setting the Web Project property, you should update the
web.config file for the MVC4 project so that it contains the required ClientId and ClientSecret entries you copied earlier. Now, turn your attention to the app project. In the AppManifest.xml file, ensure that the AppPrincipal
setting is correct for your deployment scenario. Next, set the
<StartPage> element to refer to the start page of the MVC4
project. MVC4 uses a URL format that references the controller and then
the method as opposed to webpages. The default MVC4 project template
has a controller named HomeController
that you can reference to get started. After these changes, you should
be able to run the app in debug mode because the MVC4 web project
template is already coded to show off some basic functionality with
three built-in pages. The following code shows a sample
<StartPage> URL that will work for the default template:
<StartPage>~remoteAppUrl/Home?{StandardTokens}</StartPage>
To add your own functionality to the app, you start by creating a new controller. In the MVC4 web project, right-click the Controllers
folder, and the in the settings menu that appears, click Add and click
Controller. When prompted, you can give the controller a name, ensuring
that the name ends with the string “Controller”. Figure 5 shows the addition of a ContactsController for reading list items from a contacts list.
Controllers expose public methods that return Views. Each controller has a default method named Index,
but they can have as many custom methods as you like. Custom methods
can also accept arguments that correspond to the query string
parameters contained in a URL. Example 10 shows the implementation of a method named ReadAll, which uses CSOM to read the list of clients from the app web and return a View.
Example 10. Adding a method to a controller
public ActionResult ReadAll(string SPHostUrl, string SPLanguage, string
SPAppWebUrl)
{
using (ClientContext ctx = new ClientContext(SPAppWebUrl))
{
ctx.Load(ctx.Web);
List list = ctx.Web.Lists.GetByTitle("Contacts");
ctx.Load(list);
StringBuilder caml = new StringBuilder();
caml.Append("<View><Query><OrderBy/></Query>");
caml.Append("<ViewFields><FieldRef Name='ID'/>
<FieldRef Name='FirstName'/>");
caml.Append("<FieldRef Name='Title'/><FieldRef Name='WorkPhone'/>
</ViewFields>");
caml.Append("<RowLimit>100</RowLimit></View>");
CamlQuery query = new CamlQuery();
query.ViewXml = caml.ToString();
Microsoft.SharePoint.Client.ListItemCollection listItems =
list.GetItems(query);
ctx.Load(listItems);
ctx.ExecuteQuery();
List<Contact> contacts = new List<Contact>();
foreach (ListItem listItem in listItems)
{
Contact contact = new Contact()
{
Id = listItem["ID"].ToString(),
LastName = listItem["Title"].ToString(),
FirstName = listItem["FirstName"].ToString(),
WorkPhone = listItem["WorkPhone"].ToString()
};
contacts.Add(contact);
}
ViewBag.Contacts = contacts;
}
return View();
}
If you compare Example 10 to Example 9,
you will see that the code to retrieve the list items is largely the
same. What is different is that the MVC4 code does not bind directly to
a grid. Instead, the code builds a list of contacts and saves them into
the Contacts property of the ViewBag object. The ViewBag makes data from the Controller available when the View is generated. A Controller can add properties to the ViewBag dynamically, making it simple to pass data from the Controller to the View. In this example, the Contact
class is the Model in the MVC pattern. The MVC4 project template
contains a Models folder into which you can easily add data classes
that help transfer data between the Controller and View.
A View can be added for any Controller by right-clicking within the
Controller code, and then from the settings menu that appears, clicking
Add and then clicking View. Within the View, you can define both static
and dynamic elements. Static elements set ViewBag properties to a fixed value, whereas dynamic elements use properties of the ViewBag populated by the Controller to generate results. Example 11
shows a View to generate a static title for a page and a dynamic table
containing the list items retrieved from the contacts list.
Example 11. Adding a view
@{
ViewBag.Title = "SharePoint 2013 MVC App";
}
<table id="contactsTable">
<thead><th>ID</th><th>Last Name</th><th>First Name</th><th>Work Phone</th>
</thead>
@foreach (var contact in ViewBag.Contacts)
{
<tr><td>
@contact.Id
</td><td>
@contact.LastName
</td><td>
@contact.FirstName
</td><td>
@contact.WorkPhone
</td></tr>
}
</table>
The code in Example 11 is obviously not a complete webpage. This is because the MVC4 framework supports the idea of shared views that can be merged with the partial views to create a complete webpage. In the default template, a shared view named _Layout is used to generate the basic page that is merged with the custom Views you add.
After the Views and Controllers
are created, you can invoke them through a URL. The URL format
determines which Controller method is invoked. The associated View is
then used to render the webpage. The formula for invoking a Controller
method follows the format /[Controller]/[Method]?[Parameters]. In order
to invoke the start page of your MVC4 remote web from a SharePoint app,
you must update the <StartPage> element of the AppManifest.xml file to reflect this formula. As an example, the following URL would invoke the ReadAll method of the ContactsController when the SharePoint 2013 app is launched:
~remoteAppUrl/Contacts/ReadAll?{StandardTokens}