Finally, I got the solution after lots of googling and brain-stroming. I am not able to solve the REST API - 403 error issue but I got work around for this.
I have created Web APIs in MVC project for all SharePoint operations that I wanted to do using REST API.
Create Filter for getting SharePoint context in Web API for SharePoint operations.
3 easy Steps:
1.
Change WebApiConfig.cs to enable Session State in Web API
WebApiConfig.cs
using System.Web;
using System.Web.Http;
using System.Web.Http.WebHost;
using System.Web.Routing;
using System.Web.SessionState;
namespace MyWebApi
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
RouteTable.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
).RouteHandler = new SessionRouteHandler();
}
public class SessionRouteHandler : IRouteHandler
{
IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext)
{
return new SessionControllerHandler(requestContext.RouteData);
}
}
public class SessionControllerHandler : HttpControllerHandler, IRequiresSessionState
{
public SessionControllerHandler(RouteData routeData)
: base(routeData)
{ }
}
}
}
2.
Create a new filter called SharePointContextWebAPIFilterAttribute.cs behind Filters folder.
SharePointContextFilterAttribute.cs
using System;
using System.Net;
using System.Net.Http;
using System.Web;
using ActionFilterAttribute = System.Web.Http.Filters.ActionFilterAttribute;
namespace MyWebApi
{
public class SharePointContextWebAPIFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{
if (actionContext == null)
{
throw new ArgumentNullException("actionContext");
}
Uri redirectUrl;
switch (SharePointContextProvider.CheckRedirectionStatus(HttpContext.Current, out redirectUrl))
{
case RedirectionStatus.Ok:
return;
case RedirectionStatus.ShouldRedirect:
var response = actionContext.Request.CreateResponse(System.Net.HttpStatusCode.Redirect);
response.Headers.Add("Location", redirectUrl.AbsoluteUri);
actionContext.Response = response;
break;
case RedirectionStatus.CanNotRedirect:
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.MethodNotAllowed, "Context couldn't be created: access denied");
break;
}
}
}
}
Notes in the above code:
System.Web.Http.Controllers.HttpActionContext doesn't have HttpContext object associated, so we will use HttpContext.Current instead inside OnActionExecuting when called CheckRedirectionStatus method from SharePointContextProvider class.
System.Web.Http.Controllers.HttpActionContext doesn't have Result property, we will use Response property to redirect and create Error response in the code.
3.
Use SharePointContextWebAPIFilter instead SharePointContextFilter in our Web API actions:
using Microsoft.Azure;
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web.Http;
namespace MyWebApi
{
public class MyCustomController : ApiController
{
[SharePointContextWebAPIFilter]
public string Get(string name, string number)
{
List TestAngular = null;
var spContext = SharePointContextProvider.Current.GetSharePointContext(HttpContext.Current);
using (var clientContext = spContext.CreateUserClientContextForSPHost())
{
if (clientContext != null)
{
TestAngular = clientContext.Web.Lists.GetByTitle("TestAngular");
clientContext.Load(TestAngular);
clientContext.ExecuteQuery();
ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation();
ListItem oListItem = TestAngular.AddItem(itemCreateInfo);
oListItem["Title"] = name;
oListItem["Number"] = number;
oListItem.Update();
clientContext.ExecuteQuery();
return "Data saved!";
}
else
{
return "Error occurred!";
}
}
}
}
}
How to test this approach is working
- If we go directly to our REST Service:
http://<localhost>/api/mycustom?name=TestAngular&number=1
We will receive this error:

- If we go to our SharePoint Provider-hosted app and we click on our App Launcher we will be redirected to login page and after that to an url like that:
http://<localhost>/home/index/?SPHostUrl=https%3A%2F%2Fmytenant%2Esharepoint%2Ecom&SPLanguage=en-US&SPClientTag=0&SPProductNumber=16%2E0%2E5625%2E1208&SPAppWebUrl=https%3A%2F%2Fmytenant-appguid%2Esharepoint%2Ecom&SPHasRedirectedToSharePoint=1
This isn’t our Web API, but is our gateway to login into Provider-hosted app. Once logged in, we can change the url “home/index” by our REST call, for example:
http://<localhost>/api/mycustom?name=TestAngular&number=1&SPHostUrl=https%3A%2F%2Fmytenant%2Esharepoint%2Ecom&SPLanguage=en-US&SPClientTag=0&SPProductNumber=16%2E0%2E5625%2E1208&SPAppWebUrl=https%3A%2F%2Fmytenant-appguid%2Esharepoint%2Ecom&SPHasRedirectedToSharePoint=1
That should give you the information requested in the browser.
Reference:
Use in Angular2
After creating Web API and Filter in the MVC web application, you can access that API in Angular2 using HTTP directive as per below code chunk:
let listUrl = `https://localhost/api/mycustom?name=${form.name}&number=${form.number}&SPHostUrl=https%3A%2F%2Fmytenant%2Esharepoint%2Ecom&SPLanguage=en-US&SPClientTag=0&SPProductNumber=16%2E0%2E6406%2E1200&SPAppWebUrl=https%3A%2F%2Fmytenant-appguid%2Esharepoint%2Ecom`;
let reqOptions = new RequestOptions({
url: listUrl,
method: RequestMethod.Get,
headers: new Headers({ accept: 'application/json; odata=verbose', 'content-type': 'application/json; odata=verbose' }),
body: null
});
let req = new Request(reqOptions)
this._http.request(req).map((res) => {
return res.json()
}).subscribe(data => console.log(data));
Reference:
- Use Angular 2 with Asp.Net