The MVC pattern has many of the same goals as the MVVM
pattern. The MVC pattern looks to support code reuse, maintenance, and
testing. The pattern also consists of three different components that
are similar to the ones found in the MVVM pattern. The Model component
is defined as the entities on the SharePoint server, such as lists,
libraries, and service applications. The View component is defined as
the webpages that make up the app user interface. The Controller binds
the Model and the View together. The big difference between the MVVM
pattern and the MVC pattern is that the MVVM pattern assumes that the
data in the ViewModel will persist across create, read, update, and
delete (CRUD) operations. The MVC pattern, on the other hand is
stateless. Because of the differences in how state is managed, the MVC
pattern lends itself to the development of SharePoint apps by using C#
and CSOM. Figure 2 shows a simple block diagram of the MVC pattern.
When developers think of creating SharePoint apps with C# and CSOM,
they might immediately think of using ASP.NET to create a remote web.
In fact, this is the default template used in Microsoft Visual Studio
for provider-hosted and autohosted apps. This approach involves the
development of a set of Active Server Pages (ASPX) that contain web forms, server controls, and associated C# code. The advantage of the web
forms pattern is that it is stable, mature, and well understood by web
developers. However, the web forms pattern has some limitations that
negatively impact code reuse, maintenance, and testing. Example 4-9 presents a web forms app that loads data from a contacts list in the host web and displays it in a grid.
Example 9. Using web forms in an app
protected void Page_Load(object sender, EventArgs e)
{
var contextToken = TokenHelper.GetContextTokenFromRequest(Page.Request);
var hostWeb = Page.Request["SPHostWebUrl"];
using (var clientContext = TokenHelper.GetClientContextWithContextToken(
hostWeb, contextToken, Request.Url.Authority))
{
clientContext.Load(clientContext.Web);
List list = clientContext.Web.Lists.GetByTitle("Contacts");
clientContext.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);
clientContext.Load(listItems);
clientContext.ExecuteQuery();
List<Contact> contacts = new List<Contact>();
foreach (Microsoft.SharePoint.Client.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);
}
contactsGrid.DataSource = contacts;
contactsGrid.DataBind();
}
}
Example 9 is a classic example of querying a data source and binding a grid when an ASPX
page loads. Even though this code works fine, you can see that the code
and the user interface are tightly bound. First, the code is placed
directly in the load event of the page. Second, the grid displaying the
data is directly referenced in the code. Experienced ASP.NET developers
will immediately object that such problems can be fixed in the web
forms pattern by separating the code into layers and utilizing data
binding. Although these points are certainly valid, years of experience
has taught us that web
forms apps are typically constructed with tight bindings between the
various layers. Furthermore, there is no universally accepted framework
for web forms that supports the kind of separation envisioned in the MVC pattern.
Web forms were initially envisioned to support a rapid
application development approach by which the developer is abstracted
away from the request-response details of HTTP and HTML. Web forms are
designed to simulate a stateful environment even though HTTP is
stateless. Server
controls are intended to abstract away the details of HTML so that
developers can use a visual designer to create web forms. To produce
the illusion of a stateful environment, ASP.NET stores the last state
of a web form—called the viewstate—in
a hidden field between postbacks. For complex systems, this can be a
serious issue as the viewstate becomes larger. Abstracting away the
HTML also limits the ability of the developer to support various
browser types and incorporate JavaScript libraries such as Knockout and
jQuery. Even though these limitations can be addressed in various ways,
many developers are realizing that the web forms pattern is not well
suited to developing cloud-based apps that must support millions of users and many types of browsers.