Tag Archives: REST
Explore SharePoint REST API with Chrome F12 cURL (bash) to Postman
Wanted to create demo for how to leverage F12 tools to capture SharePoint Online REST api calls and replay into REST Postman. Allows adjustment of HTTP headers, inspecting output, and execute test API calls. Postman provides benefits of storing history, export data, and fine tuning the API headers.
Leveraging Chrome F12 enables us to quickly create a valid HTTP POST with correct authentication HTTP headers, cookies, and endpoint URL. Cheers. ![]()
Video
Screenshot
Reference
VIDEO – HTTP Header Client Secret protected Web API
Watch the video below to see a demo of protecting WebAPI with HTTP header and a Client Secret. By default, new Web API projects lack any security mechanism and are open to any anonymous user. Protecting Dot Net methods with an IF() statement condition provides a simple security mechanism to ensure only users who know the Client Secret are able to run the API and execute the method.
NOTE – Check out https://www.spjeff.com/2017/10/05/video-azure-ad-protected-web-api-in-an-angularjs-spa/ for more complete WebAPI security with Azure AD.
Video
Screenshots
Code
public bool keyMatch()
{
// security HTTP header
string key = "12345678901234567890123456789012345678901234567890";
IEnumerable headerValues;
var keyFilter = string.Empty;
if (Request.Headers.TryGetValues("key", out headerValues))
{
// ALLOW - match key
keyFilter = headerValues.FirstOrDefault();
}
if (keyFilter == key)
{
return true;
}
else
{
return false;
}
} References
Custom Web Part – Save settings to SPList (without jQuery)
Ever wanted to code a JavaScript content editor (script editor) web part that saves settings to a list? Without jQuery?
The library below “wp-settings.js” does exactly that with native XHR (XML HTTP Request) and nested callback to invoke REST API. The free standing POJO (Plan Old JavaScript Object) design enables us to package into a web part gallery and use freely across any site without preparation work to ensure jQuery, Angular, or other dependent frameworks are loaded.
Look at the “webpart.html” to see example usage pattern:
- wpsRead() Get settings (if any)
- wpInit() Local web part initialize
- wpsWrite() Save settings (UPDATE/INSERT)
Source Code
Video
Screenshots
References
SPAuditAPI – Read SharePoint audit logs from JavaScript over REST
Recently I wanted to query Audit data from the web browser client and learned no native REST api was available. So I created one. Below is a demonstration video and link to the full source code.
This web API enables us to execute the server object model SPAuditQuery() method from HTTP POST and provide optional filter parameters. More filters give a narrow match and faster server response. We want to be specific, even if only a default time range (example – past 30 days) to improve user experience and reduce system load.
Source Code
Video
Context Diagram
Screen Shots
VIDEO – Online WebAPI Generator
I created an online service at https://spjeff.azurewebsites.net/ which generates a MVC WebAPI 2.2 project with the name you enter. A custom ZIP file is generated server side with your custom name for the Project, Namespaces, Assembly, and sent to the browser for download. Best practices are already enabled such as:
- [CORS] decorator
- [Authorize] decorator
- Minimal packages and dependency
- Zero MVC boilerplate
- Lean mean API ready for dev & prod
From there double click SLN and begin coding. Enjoy! ![]()
Video
Online WebAPI Generator from Jeff Jones on Vimeo.
Screenshots
AngularJS – $http default JSON headers
The below JavaScript will change $http default headers to be JSON ready for SharePoint REST APIs. This is handy when sending GET/POST to SharePoint 2013 so we don’t need to repeat headers on each individual call. Enjoy! ![]()
//namespace
var namespace = namespace || {};
//NG-controller
namespace.myCtl = function ($scope, $mySvc) {
//viewmodel
var vm = $scope;
};
//NG-service
namespace.mySvc = function ($q, $http) {
$http.defaults.headers.common['Accept'] = 'application/json;odata=verbose';
//User Profile - me
this.getMe = function () {
return $http.get('/_api/SP.UserProfiles.PeopleManager/GetMyProperties');
};
//User Profile - users
this.getUser = function (login) {
var url = '/_api/SP.UserProfiles.PeopleManager/GetPropertiesFor(accountName=@v)?@v=\'domain\\' + login + '\'';
return $http.get(url);
};
};
//NG-module
angular.module('myApp', [])
.controller('myCtl', namespace.myCtl)
.service('$mySvc', namespace.mySvc)
.run(function () {
//prepare GUI
});WebAPI OData – 10 min video introduction (Visual Studio 2013)
I’ve been learning about OData and wanted to record a quick getting started video with how to create a new WebAPI project, add OData Controller, and send HTTP CRUD operations. Below is an example using Adventure Works Departments with sample code, screenshots, and a 10 minute video introduction. Please leave a comment if you found this helpful. Thanks! ![]()
Video Content
- Create MVC 4 web application
- SQL Express – Adventure Works Departments
- Add “AdventureWorks.edmx”
- Wizard driven
- F4 set namespace
- Add “DepartmentsController.cs”
- Create from EDMX class
- Implements ODataController
- Replace ID with KEY
- Edit “WebApiConfig.cs”
- Comment out default route
- Add OData route builder
- Test with HTTP manually
- Test with Chrome REST Postman
- SQL Express – see changed data
Watch Video
WebAPI OData – 10 min video introduction (Visual Studio 2013) from Jeff Jones on Vimeo.
Sample Code
[WebApiConfig.cs]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using System.Web.Http.OData.Builder;
namespace MvcApplication1
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//config.Routes.MapHttpRoute(
// name: "DefaultApi",
// routeTemplate: "api/{controller}/{id}",
// defaults: new { id = RouteParameter.Optional }
//);
ODataConventionModelBuilder build = new ODataConventionModelBuilder();
build.EntitySet("Departments");
config.Routes.MapODataRoute("odata", "odata", build.GetEdmModel());
config.EnableQuerySupport(new QueryableAttribute());
// Uncomment the following line of code to enable query support for actions with an IQueryable or IQueryable return type.
// To avoid processing unexpected or malicious queries, use the validation settings on QueryableAttribute to validate incoming queries.
// For more information, visit http://go.microsoft.com/fwlink/?LinkId=279712.
//config.EnableQuerySupport();
// To disable tracing in your application, please comment out or remove the following line of code
// For more information, refer to: http://www.asp.net/web-api
config.EnableSystemDiagnosticsTracing();
}
}
}
[DepartmentsController.cs]
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using System.Web.Http.OData;
namespace MvcApplication1.Controllers
{
public class DepartmentsController : ODataController
{
private AdventureWorks2012Entities db = new AdventureWorks2012Entities();
// GET api/Default1
public IEnumerable GetDepartments()
{
return db.Departments.AsEnumerable();
}
// GET api/Default1/5
public Department GetDepartment(short key)
{
Department department = db.Departments.Find(key);
if (department == null)
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
}
return department;
}
// PUT api/Default1/5
public HttpResponseMessage PutDepartment(short key, Department department)
{
if (!ModelState.IsValid)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
if (key != department.DepartmentID)
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
db.Entry(department).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
}
return Request.CreateResponse(HttpStatusCode.OK);
}
// POST api/Default1
public HttpResponseMessage PostDepartment(Department department)
{
if (ModelState.IsValid)
{
db.Departments.Add(department);
db.SaveChanges();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, department);
response.Headers.Location = new Uri(Url.Link("odata", new { key = department.DepartmentID }));
return response;
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
}
// DELETE api/Default1/5
public HttpResponseMessage DeleteDepartment(short key)
{
Department department = db.Departments.Find(key);
if (department == null)
{
return Request.CreateResponse(HttpStatusCode.NotFound);
}
db.Departments.Remove(department);
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
}
return Request.CreateResponse(HttpStatusCode.OK, department);
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
}
