walkthrough: deploying a signalr autohosted app to web viewwalkthrough: deploying a signalr...

31
Walkthrough: Deploying a SignalR autohosted App to Office 365 WRITTEN BY ELLIOT WOOD AND MATT MENEZES Step 1: Add an App for SharePoint 2013 project to your solution New project > SharePoint App

Upload: nguyenphuc

Post on 06-Feb-2018

222 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver

Walkthrough: Deploying a SignalR autohosted App to Office 365WRITTEN BY ELLIOT WOOD AND MATT MENEZES

Step 1: Add an App for SharePoint 2013 project to your solutionNew project > SharePoint App

Step 2: Add proxy AutoDetect (if you are behind one)

The following code should be manually added to the web.config file:

Page 2: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver

<system.net> <defaultProxy> <proxy autoDetect="True" /> </defaultProxy> </system.net>

Step 3: Configure your App to include an App Event ReceiverGoto your App’s properties window, Set Handle App Installed to True

Step 4: Add a Remote Event Receiver to your AppAdd a New Item to the SharePoint app project

Page 3: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver

Select Remote Event Receiver, and click Add

Choose List Item Events, and Custom list (We can ignore this event source as we will register one manually later on).

Choose to handle the following events: An item is being added, updated, deleted. Click Finish.

Page 4: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver

Step 5: Configure the required permissions for your AppGive your app Full Control permissions to the Web and List

Page 5: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver

Step 6: Add a Global.asax file to your App Web projectIn your web project Add a Global Application Class called Global

Then add the following code

using Microsoft.AspNet.SignalR;

Page 6: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver

using System;using System.Web.Routing;

namespace SharePointRWeb{ public class Global : System.Web.HttpApplication { protected void Application_Start(object sender, EventArgs e) { var hubConfiguration = new HubConfiguration(); hubConfiguration.EnableCrossDomain = true; hubConfiguration.EnableDetailedErrors = true; RouteTable.Routes.MapHubs("/signalr", hubConfiguration); } }}

Step 7: Add the SignalR Hub class to your App Web projectGo to your web project and Add a New Item

Page 7: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver

Add a SignalR Hub Class

Also add a new Class, we are going to call ours SharePointR

Page 8: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver

Add the following code to the new class

using Microsoft.AspNet.SignalR;using Microsoft.AspNet.SignalR.Hubs;using System;

namespace SharePointRWeb{ public class SharePointR { // Singleton instance private readonly static Lazy<SharePointR> _instance = new Lazy<SharePointR>(() => new SharePointR(GlobalHost.ConnectionManager.GetHubContext<SharePointRHub>().Clients)); public SharePointR(IHubConnectionContext clients) { Clients = clients; } public static SharePointR Instance { get { return _instance.Value; } } private IHubConnectionContext Clients { get; set; } public void NotifyDataChanged(string ListName, string Event) { Clients.Group(ListName).dataChanged(Event); } }}

Page 9: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver

Edit the hub class and add the following code

using Microsoft.AspNet.SignalR;using Microsoft.AspNet.SignalR.Hubs;

namespace SharePointRWeb{ [HubName("SharePointRHub")] public class SharePointRHub : Hub { private readonly SharePointR _sharePointR;

public SharePointRHub() : this(SharePointR.Instance) { }

public SharePointRHub(SharePointR sharePointR) { _sharePointR = sharePointR; }

public void Subscribe(string ListName) { Groups.Add(Context.ConnectionId, ListName); }

public void UnSubscribe(string ListName) { Groups.Remove(Context.ConnectionId, ListName); }

public void NotifyDataChanged(string ListName, string Event) { _sharePointR.NotifyDataChanged(ListName, Event); } }}

Page 10: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver

Step 8: Configure the App Event Receiver to manually bind the Item Event Receivers to a given ListOpen the App Event Receiver code behind. Add the code below which will manually hook up an item event receiver to a list in the host web (for the example we use the Announcements list). You can easily hook this up to more than one list here and because we implement a subscribe model above, the client will only receive the items they are subscribed to.

using System.Collections.Generic;using System.Linq;using Microsoft.SharePoint.Client;using Microsoft.SharePoint.Client.EventReceivers;using System.ServiceModel;using System.Reflection;

namespace SharePointRWeb.Services{ public class AppEventReceiver : IRemoteEventService { private string ReceiverName = "RemoteEventReceiver"; private List<EventReceiverType> EventType = new List<EventReceiverType>() { EventReceiverType.ItemAdding, EventReceiverType.ItemUpdating, EventReceiverType.ItemDeleting }; private string ListTitle = "Announcements";

public SPRemoteEventResult ProcessEvent(SPRemoteEventProperties properties) { SPRemoteEventResult result = new SPRemoteEventResult();

using (ClientContext clientContext = TokenHelper.CreateAppEventClientContext(properties, false)) { Web hostWeb = clientContext.Web;

Page 11: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver

clientContext.Load(hostWeb);

List docLib = clientContext.Web.Lists.GetByTitle(ListTitle);

string opContext = OperationContext.Current.Channel.LocalAddress.Uri.AbsoluteUri.Substring(0, OperationContext.Current.Channel.LocalAddress.Uri.AbsoluteUri.LastIndexOf("/")); string remoteUrl = string.Format("{0}/RemoteEventReceiver.svc", opContext);

if (properties.EventType == SPRemoteEventType.AppInstalled) { foreach (var eventType in EventType) { EventReceiverDefinitionCreationInformation newEventReceiver = new EventReceiverDefinitionCreationInformation() { EventType = eventType, ReceiverAssembly = Assembly.GetExecutingAssembly().FullName, ReceiverClass = "SignalRProxyService.Services.RemoteEventReceiver", ReceiverName = ReceiverName + eventType.ToString(), ReceiverUrl = remoteUrl, SequenceNumber = 1000 }; docLib.EventReceivers.Add(newEventReceiver); } clientContext.ExecuteQuery(); } else if (properties.EventType == SPRemoteEventType.AppUninstalling) { IEnumerable<EventReceiverDefinition> receivers = clientContext.LoadQuery(docLib.EventReceivers .Where(e => e.ReceiverName == ReceiverName));

foreach (var rec in receivers) { rec.DeleteObject(); } clientContext.ExecuteQuery(); } } return result; }

public void ProcessOneWayEvent(SPRemoteEventProperties properties) { // This method is not used by app events } }}

Note: For synchronous “-ing” events (like  adding, deleting, updating)  you must use the ProcessEvent method. For asynchronous  ”-ed”  events (like  added, updated, deleted), use the ProcessOneWayEvent method.

Page 12: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver

Step 9: Configure the Remote Event Receiver to communicate with the page via SignalR

Open the Remote Event Receiver code behind, add the following code. This will notify the hub when events occur.

using System;using System.Collections.Generic;using System.Linq;using System.Text;using Microsoft.SharePoint.Client;using Microsoft.SharePoint.Client.EventReceivers;

namespace SharePointRWeb.Services{ public class RemoteEventReceiver : IRemoteEventService { private SharePointRHub client = new SharePointRHub();

public SPRemoteEventResult ProcessEvent(SPRemoteEventProperties properties) { client.NotifyDataChanged(properties.ItemEventProperties.ListTitle, properties.EventType.ToString()); return new SPRemoteEventResult(); ; }

public void ProcessOneWayEvent(SPRemoteEventProperties properties) {

} }}

Page 13: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver

Step 10: Create the page that will receive the SignalR messages (including slight branding to the page fits the site)Using Manage NuGet Packages add the json2 package.

Page 14: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver

It will add json2 to the Scripts directory

Add a new JavaScript File called chromeLoader.js, this will allow our app to be branded correctly.

// Callback for the onCssLoaded event defined

Page 15: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver

// in the options object of the chrome controlfunction chromeLoaded() { // When the page has loaded the required // resources for the chrome control, // display the page body. $("body").show();}

//Function to prepare the options and render the controlfunction renderChrome() { // The Help, Account and Contact pages receive the // same query string parameters as the main page var options = { "appIconUrl": "/Images/AppIcon.png", "appTitle": "SignalR Sample Application", "appHelpPageUrl": "default.aspx?" + document.URL.split("?")[1], // The onCssLoaded event allows you to // specify a callback to execute when the // chrome resources have been loaded. "onCssLoaded": "chromeLoaded()", "settingsLinks": [ { "linkUrl": "Account.html?" + document.URL.split("?")[1], "displayName": "Account settings" }, { "linkUrl": "Contact.html?" + document.URL.split("?")[1], "displayName": "Contact us" } ] };

var nav = new SP.UI.Controls.Navigation( "chrome_ctrl_placeholder", options ); nav.setVisible(true);}

// Function to retrieve a query string value.// For production purposes you may want to use// a library to handle the query string.function getQueryStringParameter(paramToRetrieve) { var params = document.URL.split("?")[1].split("&"); var strParams = ""; for (var i = 0; i < params.length; i = i + 1) { var singleParam = params[i].split("="); if (singleParam[0] == paramToRetrieve) return singleParam[1]; }}

var hostweburl;

//load the SharePoint resources$(document).ready(function () { //Get the URI decoded URL. hostweburl = decodeURIComponent(

Page 16: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver

getQueryStringParameter("SPHostUrl") );

// The SharePoint js files URL are in the form: // web_url/_layouts/15/resource var scriptbase = hostweburl + "/_layouts/15/";

// Load the js file and continue to the // success handler $.getScript(scriptbase + "SP.UI.Controls.js", renderChrome)});

In the web project go to the default.aspx.cs file under /pages, replace the code behind with the following

using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.UI;using System.Web.UI.WebControls;

namespace SharePointRWeb.Pages{ public partial class Default : System.Web.UI.Page { public string SiteTitle = string.Empty;

protected void Page_Load(object sender, EventArgs e) { // The following code gets the client context and Title property by using TokenHelper. // To access other properties, you may need to request permissions on the host web.

var contextToken = TokenHelper.GetContextTokenFromRequest(Page.Request); var hostWeb = Page.Request["SPHostUrl"];

Page 17: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver

using (var clientContext = TokenHelper.GetClientContextWithContextToken(hostWeb, contextToken, Request.Url.Authority)) { clientContext.Load(clientContext.Web, web => web.Title); clientContext.ExecuteQuery();

SiteTitle = clientContext.Web.Title; } } }}

In the web project go to the default.aspx file under /pages, replace the mark-up with the following:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="SharePointRWeb.Pages.Default" %><!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head> <title>SignalR Sample</title></head><!-- The body is initally hidden. The onCssLoaded callback allows you to display the content after the required resources for the chrome control have been loaded. --><body style="display:none;"> <!-- Chrome control placeholder --> <div id="chrome_ctrl_placeholder"></div> <!-- The chrome control also makes the SharePoint Website stylesheet available to your page --> <h1 id="HostSiteTitle" class="ms-accentText"><%= this.SiteTitle %></h1> <div id="MainContent"></div> <!--Script references. --> <script src="//ajax.aspnetcdn.com/ajax/4.0/1/MicrosoftAjax.js"></script> <!--Reference the jQuery/JSON library. --> <script src="/Scripts/jquery-1.8.2.min.js"></script> <script src="/Scripts/json2.js"></script> <!--Reference the chromeLoader helper. --> <script src="/Scripts/chromeLoader.js"></script> <!--Reference the SignalR library. -->

Page 18: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver

<script src="/Scripts/jquery.signalR-1.0.0.js"></script> <!--Reference the autogenerated SignalR hub script. --> <script src="/signalr/hubs"></script>

<!--Add script to update the page and send messages.--> <script type="text/javascript"> $(function () { var connection = $.hubConnection('/signalr/hubs'); proxy = connection.createHubProxy('SharePointRHub') proxy.on('dataChanged', function (eventType) { $('#MainContent').append('<li>Data changed - ' + eventType + '</li>'); }); connection.start() .done(function () { //Subscribe to Announcements list proxy.invoke('Subscribe', "Announcements"); $('#MainContent').append('<span>Now connected, connection ID=' + connection.id + '</span>'); }) .fail(function () { $('#MainContent').append('<span>Could not Connect!</span>'); }); }); </script></body></html>

Go to the app project and edit the appmanifest, goto the genral tab and add the following to the QueryString “{StandardTokens}&SPHostTitle={HostTitle}” required for branding.

in the web project add an Images folder

Page 19: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver

Add and and image called “AppIcon.png” to the Images folder

Page 20: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver

Step 11: Create the list in SharePoint that the event receiver will be bound toGo to your SharePoint site create a list called Announcements

Step 12: Deploy the App to Office 365Now press F6 or Build Solution

Page 21: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver

And click Deploy

note: If you receive an error here see troubleshooting as the bottom.

Trust the app and now it is ready for use (details below)

Alternatively You may want to deploy the app to the app catalog (recommended for production).

Publish the app

Page 22: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver

.

Page 23: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver
Page 24: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver

Now the app is published here is a step by step guide to how to deploy it.

Go to your App Catalog Site (you may need to create one, tutorial not included here) in site contents go to apps for SharePoint

Page 25: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver

Drag your published app to the library to deploy it

Add an app > SharePointR

Page 26: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver
Page 27: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver

Trust the app

Step 13: Run the App!Open the announcements list side by side with the Page that will receive the SignalR messages. Add/Edit/Remove items from the list and watch the magic.

Page 28: Walkthrough: Deploying a SignalR autohosted App to Web viewWalkthrough: Deploying a SignalR autohosted App to Office 365. ... Step 3: Configure your App to include an App Event Receiver

Appendix: Troubleshooting

When publishing a SharePoint hosted application to a development site on Office 365 Preview, running SharePoint 2013, you may receive the following error:

“Error occurred in deployment step ‘Install App for SharePoint’: Sideloading of apps is not enabled on this site.

Solution: You need to enable the Sideloading feature on the site.

1. Download and install the SharePoint Online Management Shell for PowerShell

2. Download the script Sideload.ps1 and execute it within the SharePoint Online Management Shell.

Note: This is not recommended for a production site. Deploy applications using the App Catalog on a production site.

Source “http://blog.lekman.com/2012/11/sharepoint-2013-sideloading-of-apps-is.html”

I used the following code to enable the feature on my host site

using (var context = new ClientContext(Url)) { //Pass the Credentials to SharePoint Online context.Credentials = new SharePointOnlineCredentials(UserName, Password);

var site = context.Site; context.Load(site); context.ExecuteQuery();

site.Features.Add(new Guid("E374875E-06B6-11E0-B0FA-57F5DFD72085"), true, FeatureDefinitionScope.Farm); context.ExecuteQuery();

}