SharePoint 2013 App with Page that gets data from ASP Web Api
The specific scenario I am trying to address here is when you have a page that is deployed into the SharePoint AppWeb and you are trying to access data from that AppWeb using a WebApi project for example.
You might be trying to create a SharePoint Hosted App with a separate WebApi project that you are planning host on your own. The issue arises when the SharePoint Hosted Page tries to access the data from the WebApi site. You will get an error that looks something like so.
XMLHttpRequest cannot load http://localhost:54924/api/actionlogs. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://app-0807f4294057b3.sharepoint.com' is therefore not allowed access.
The issue here relates to Cross-Origins Request, in that the WebApi site gets a
request from a domain different to that of its own and hence rejects the
request. To get around this, you could have the server accept requests from any
domains. This can be achieved by adding config.EnableCors();
to the
WebApiConfig.Register
method. And then adding the attribute
[EnableCors(origins: "*", headers: "*", methods: "*")]
to each of the
ApiControllers. Further information on Cross-Origin Request can be found on
this blog by Mike Wasson.
Issue specific to SharePoint apps hosted in Office 365 is that you cannot
predict the URL of the domain the app will end up in. We cannot add a URL such
as "*.sharepoint.com"
. The domain URL has to be either "*"
or the full
server address.
One easy fix is to save the name of the server into database when the app is installed. This can be achieved by the use of app event receivers. I am sure that you can have a SharePoint Hosted App which talks to a remote service for event receivers. But, when you add App Installation Handler to a SharePoint Hosted App, Visual Studio creates a new project for you and changes the appmanifest to say AutoHosted App.
An empty web project is added to the solution. Notice that the Hosting type
value changed to say Autohosted
.
I believe, if you would like to keep your SharePoint App as SharePoint hosted,
simply replace the ~remoteAppUrl
part of the value for
Properties/InstalledEventEndpoint
in your appmanifest.xml
to point to your
actual service project.
To save the app web host URL to the database, open the project property window for your SharePoint project and set the values for Handle App Installed and Handle App Uninstalled to True.
Make sure you have a Azure Service Bus namespace created and you copy the
connection string to SharePoint project Properties Window / SharePoint tab /
Service Bus Connection String text area. I am not sure why you need this. If
you don’t, when the installation completes, you get an error which says
there is no end point listening at localhost:4563/Services/AppEventReceiver.svc
Now, in the file Services/AppEventReceiver.svc
in your remote web project,
replace the code in the ProcessEvent
method with the following:
The approach above was borowed from the Core.EventReceivers project in the App Model Sample v2 over at CodePlex. Create the following private method for handling app install and app uninstall.
Now, in the MyCorsPolicyAttribute
file, replace the code with adds two host
address manually with these code.
The full code for this sample project can be downloaded from here. The solution provided is not final and would appreciate your contributions :)