Web API
Created by Orckestra
Example 1: CRUD using JavaScript
How to use Web API to perform CRUD operations with JavaScript on a static data type
In the following example, we'll create a static data type ("Product") and build a Web API that will serve as a web point for CRUD operations on this type. Then we'll create a C1 Razor function that will perform these CRUD operations via AJAX+JSON requests.
Creating a Visual Studio project
- Make sure you've installed the Composite.AspNet.WebAPI package.
- Create a Class Library project in Visual Studio naming it, for example, "WebApiDemo".
- Add references to
Composite.dll
,Microsoft.Practices.EnterpriseLibrary.Validation.dll
andSystem.Web.Http.dll
on your website (/Bin
)
Creating a static data type
- Add an interface called "Product".
- Replace the default content of the generated code with this code:
using Composite.Core.WebClient.Renderings.Data; using Composite.Data; using Composite.Data.Hierarchy; using Composite.Data.Hierarchy.DataAncestorProviders; using Composite.Data.Validation.Validators; using Microsoft.Practices.EnterpriseLibrary.Validation.Validators; using System; namespace WebApiDemo { [AutoUpdateble] [DataScope("public")] [RelevantToUserType("Developer")] [DataAncestorProvider(typeof(NoAncestorDataAncestorProvider))] [ImmutableTypeId("e46dcbcf-2da7-4267-8fae-2624328e3d63")] [KeyTemplatedXhtmlRenderer(XhtmlRenderingType.Embedable, "<span>{label}</span>")] [KeyPropertyName("Id")] [Title("Product")] [LabelPropertyName("Title")] public interface Product : IData { [ImmutableFieldId("ed5f44c3-cb4a-4c5e-b76c-f952c991d79b")] [DefaultFieldNewGuidValue] [StoreFieldType(PhysicalStoreFieldType.Guid)] [NotNullValidator] [FieldPosition(-1)] Guid Id { get; set; } [ImmutableFieldId("fb0daafa-80f6-48d5-801c-7f712fc4d079")] [StoreFieldType(PhysicalStoreFieldType.String, 64)] [NotNullValidator] [FieldPosition(0)] [StringSizeValidator(0, 64)] [DefaultFieldStringValue("")] [TreeOrdering(1)] string Title { get; set; } [ImmutableFieldId("2d412b4d-f2bd-483e-bb74-8ca0631c7d3a")] [StoreFieldType(PhysicalStoreFieldType.Integer)] [FieldPosition(1)] [IntegerRangeValidator(-2147483648, 2147483647)] [DefaultFieldIntValue(0)] int Price { get; set; } } }
- Use
EnsureCreateStore
on the application startup to ensure that the data type has been created:using Composite.Core.Application; using Composite.Data.DynamicTypes; namespace WebApiDemo { [ApplicationStartup] internal static class StartupHandler { public static void OnBeforeInitialize() { } public static void OnInitialized() { DynamicTypeManager.EnsureCreateStore(typeof (Product)); } } }
Download the sample code
Creating a Web API
- Add a "controller" class that inherits from ApiController and implement the Web API.
- Replace the default content of the generated code with this code:
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Web.Http; using Composite.Data; namespace WebApiDemo { public class ProductController : ApiController { // Getting the list of products public IEnumerable<Product> Get() { using (var c = new DataConnection()) { return c.Get<Product>().OrderBy(p => p.Title).ToList(); } } // Getting a product by id public Product Get(Guid id) { using (var c = new DataConnection()) { return c.Get<Product>().FirstOrDefault(p => p.Id == id); } } // Adding a new product public Product PostProduct(Product product) { using (var c = new DataConnection()) { product.Id = Guid.NewGuid(); return c.Add(product); } } // Updating an existing Product public void PutProduct(Guid id, Product productJson) { using (var c = new DataConnection()) { var product = c.Get<Product>().FirstOrDefault(p => p.Id == id); if (product == null) { throw new HttpResponseException(HttpStatusCode.NotFound); } product.Title = productJson.Title; product.Price = productJson.Price; c.Update(product); } } // Deleting a new product public void DeleteProduct(Guid id) { using (var c = new DataConnection()) { var product = c.Get<Product>().FirstOrDefault(p => p.Id == id); if (product != null) { c.Delete(product); } } } } }
Download the sample code
Adding the WebApiDemo to the website
- Build the project.
- Copy
WebApiDemo.dll
from\WebApiDemo\bin\Release
(or
) to\WebApiDemo\bin
\Debug~
/Bin on your website.
Creating a C1 Razor function for CRUD operations
- Log in to the C1 Console.
- In the Functions perspective, add a new Razor function called "WebApiCrudExample".
- Replace the generated code with this code:
@using WebApiDemo @inherits RazorFunction @functions { public override string FunctionDescription { get { return "A demo function that outputs a hello message."; } } } @{ Response.Cache.SetCacheability(HttpCacheability.NoCache); } <html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://www.composite.net/ns/function/1.0"> <head> <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.12.0/jquery.validate.min.js"></script> <script src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script> <script type="text/javascript"> // <!-- function LoadJson(url) { $.getJSON(url, function (data) { $("#jsonResult")[0].textContent = JSON.stringify(data, null, 2); }); } function AddProduct() { if (!$("#title").valid() || !$("#price").valid()) { return; } var product = { Title: $("#title")[0].value, Price: parseInt($("#price")[0].value) }; $.ajax({ url: '/api/product/', type: 'POST', data: JSON.stringify(product), contentType: "application/json;charset=utf-8", success: function (data) { alert('Product added Successfully'); UpdateProductList(); }, error: function (message) { alert('Product not Added: ' + JSON.stringify(message)); } }); return false; } function OpenForEditing(productId) { $.getJSON('/api/product/' + productId, function (data) { $("#edit_id")[0].value = data.Id; $("#edit_title")[0].value = data.Title; $("#edit_price")[0].value = data.Price; $("#editProductForm").show(); $("#editProductForm")[0].scrollIntoView(); }); } function EditProduct() { if (!$("#edit_title").valid() || !$("#edit_price").valid()) { return; } var product = { Id: $("#edit_id")[0].value, Title: $("#edit_title")[0].value, Price: $("#edit_price")[0].value }; $.ajax({ type: "PUT", url: '/api/product/' + product.Id, data: JSON.stringify(product), contentType: "application/json; charset=utf-8", dataType: "json", processData: true, success: function (data, status, jqXHR) { UpdateProductList(); $("#editProductForm").hide(); }, error: function (xhr) { alert(xhr.responseText); } }); } function RemoveProduct(productId) { $.ajax({ type: "DELETE", url: "/api/product/" + productId, contentType: "json", dataType: "json", success: function (data) { document.getElementById(productId).remove(); }, error: function (xhr) { alert(xhr.responseText); } }); } $.template("productRowTemplate", "<tr id='${Id}'><td> ${Title} </td> <td> ${Price} </td>" + " <td> <a href='javascript:return false;' onclick=\"OpenForEditing('${Id}')\"> Edit </a></td>" + " <td> <a href='javascript:return false;' onclick=\"RemoveProduct('${Id}')\"> Remove </a></td></tr>"); function UpdateProductList() { $.getJSON("/api/product", function (data) { $("#productRows")[0].innerHTML = ""; $.tmpl("productRowTemplate", data).appendTo("#productRows"); }); } $(function() { $('#addProductForm').validate(); UpdateProductList(); }); //--> </script> <style type="text/css"> .queryLink { display: inline-block; background-color: lightblue; padding: 10px 20px; } #productRows tr { border-bottom: 2px solid black; } #productRows td, .productList thead td { padding: 10px; } </style> </head> <body> <h1>Add a product</h1> <form id="addProductForm" method="POST" action="#" role="form"> <div class="form-group"> <label for="title">Title</label> <input type="text" class="required" name="title" id="title" /> </div> <div class="form-group"> <label for="title">Price</label> <input type="text" class="number required" name="price" id="price" /> </div> <a class="btn btn-default" href="javascript: return false;" onclick="AddProduct()"> Add </a> </form> <h2>List of products</h2> <table class="productList"> <thead> <tr> <td>Title</td> <td>Price</td> <td></td> </tr> </thead> <tbody id="productRows"> </tbody> </table> <div id="editProductForm" style="display: none"> <h1>Edit product form</h1> <form id="editProductForm" method="POST" action="#" role="form"> <input type="hidden" id="edit_id" /> <div class="form-group"> <label for="title">Title</label> <input type="text" class="required" name="title" id="edit_title" /> </div> <div class="form-group"> <label for="title">Price</label> <input type="text" class="number required" name="price" id="edit_price" /> </div> <a class="btn btn-default" href="javascript: return false;" onclick="EditProduct()"> Edit </a> </form> </div> <h1>JSON result example</h1> <a href="javascript:return false;" onclick="LoadJson('/api/product')" class="queryLink"> Get Products JSON </a> <pre id="jsonResult" style="padding: 10px; max-width: 700px; border: 2px solid black"> </pre> </body> </html>
Download the sample code - Edit or create a page.
- Insert this function on the page.
- Save and publish the page.
Testing the demo
Now you can perform CRUD operations with the "Products" data type on the page.
- Open the page where you inserted the "WebApiCrudExample" function.
- Do one of the following:
- Add a product.
- Edit or remove a product.
- View the list of products.
- Get the product data in JSON format.