{"id":3822,"date":"2016-11-25T16:00:45","date_gmt":"2016-11-25T12:00:45","guid":{"rendered":"https:\/\/dhtmlx.com\/blog\/?p=3822"},"modified":"2025-03-10T16:32:32","modified_gmt":"2025-03-10T13:32:32","slug":"using-dhtmlx-gantt-chart-asp-net-rest-api","status":"publish","type":"post","link":"https:\/\/dhtmlx.com\/blog\/using-dhtmlx-gantt-chart-asp-net-rest-api\/","title":{"rendered":"Using DHTMLX Gantt Chart with ASP.NET and REST API"},"content":{"rendered":"<p>Today, we&#8217;ll talk about creating a <a href=\"\/\/dhtmlx.com\/docs\/products\/dhtmlxGantt\/\">Gantt chart<\/a> application with ASP.NET and REST API on the server-side. We will make use of ASP.NET MVC 5 web platform and Web API 2 Controller for REST API to create a Gantt application. To organize communication with the database, we will use the <a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/entity-framework\" target=\"_blank\">Entity Framework<\/a>. We will build our application with the help of the MS Visual Studio 2015 IDE.<\/p>\n<p>And now, let&#8217;s start by running Visual Studio and creating a new project.<\/p>\n<h3><strong>Step 1. Creating a New Project<\/strong><\/h3>\n<p>Open the <em>File<\/em> menu tab and choose: <em>New -&gt; Project<\/em>. Then select <em>ASP.NET Web Application<\/em> and give it a name. We&#8217;ll name it <em>gantt-rest-net<\/em> for our example:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3832\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/vs_project.png\" alt=\"vs_project\" width=\"671\" height=\"492\" srcset=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/vs_project.png 671w, https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/vs_project-300x220.png 300w\" sizes=\"auto, (max-width: 671px) 100vw, 671px\" \/><\/p>\n<p>Select an Empty project among available templates and check <em>MVC<\/em> and <em>Web API<\/em> checkboxes below the list of templates:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3831\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/select_template.png\" alt=\"select_template\" width=\"451\" height=\"419\" srcset=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/select_template.png 451w, https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/select_template-300x279.png 300w\" sizes=\"auto, (max-width: 451px) 100vw, 451px\" \/><\/p>\n<p>Now, we need to install dhtmlxGantt using NuGet. Run the following command in the Package Manager Console:<\/p>\n<div class=\"codecolorer-container csharp default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"csharp codecolorer\">Install<span class=\"sy0\">-<\/span>Package DHTMLX<span class=\"sy0\">.<\/span><span class=\"me1\">Gantt<\/span><\/div><\/div>\n<h3><strong>Step 2. Adding Models, Views, and Controllers<\/strong><\/h3>\n<p>At this step we have three main tasks:<\/p>\n<ul>\n<li>Creating <strong>Models<\/strong>, special objects that will represent data in the Gantt chart<\/li>\n<li>Creating <strong>Views<\/strong> that will visualize the data<\/li>\n<li>Creating <strong>Controller<\/strong> that will process the requests that come from the user and run the needed logic. It&#8217;ll call a particular view to generate a necessary HTML for the request<\/li>\n<\/ul>\n<p>We&#8217;ll start from creating a controller.<\/p>\n<h4>Creating a Controller<\/h4>\n<p>Call the context menu for the <em>Controllers<\/em> folder and choose <em>Add-&gt;Controller<\/em>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3827\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/creating_controller.png\" alt=\"creating_controller\" width=\"667\" height=\"366\" srcset=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/creating_controller.png 667w, https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/creating_controller-300x165.png 300w\" sizes=\"auto, (max-width: 667px) 100vw, 667px\" \/><\/p>\n<p>In the opened window select <em>MVC 5 Controller -&gt; Empty<\/em> and name a newly added controller <em>&#8220;HomeController&#8221;<\/em>.<\/p>\n<p>Our controller has the Index() method of the ActionResult class by default, so it doesn&#8217;t require any additional logic. All we need to do is to add a view for it:<\/p>\n<p>&nbsp;<\/p>\n<p>using System;<br \/>\nusing System.Collections.Generic;<br \/>\nusing System.Linq;<br \/>\nusing System.Web;<br \/>\nusing System.Web.Mvc;<\/p>\n<p>namespace gantt_rest_net.Controllers<br \/>\n{<br \/>\npublic class HomeController : Controller<br \/>\n{<br \/>\n\/\/ GET: Home<br \/>\npublic ActionResult Index()<br \/>\n{<br \/>\nreturn View();<br \/>\n}<br \/>\n}<br \/>\n}<\/p>\n<h4>Creating a View<\/h4>\n<p>In the <em>Views<\/em> folder find the <em>Home<\/em> directory. Right click on it to call the context menu and select <em>Add -&gt; View<\/em>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3829\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/creating_view.png\" alt=\"creating_view\" width=\"705\" height=\"462\" srcset=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/creating_view.png 705w, https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/creating_view-300x197.png 300w\" sizes=\"auto, (max-width: 705px) 100vw, 705px\" \/><\/p>\n<p>Name the new view <em>&#8220;Index&#8221;<\/em>, then open the newly created view and put the following code into it:<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"sy0\">@<\/span><span class=\"br0\">&#123;<\/span><br \/>\nViewBag.<span class=\"me1\">Title<\/span> <span class=\"sy0\">=<\/span> <span class=\"st0\">&quot;Index&quot;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"sy0\">&lt;<\/span>script src<span class=\"sy0\">=<\/span><span class=\"st0\">&quot;~\/scripts\/dhtmlxgantt.js&quot;<\/span> type<span class=\"sy0\">=<\/span><span class=\"st0\">&quot;text\/javascript&quot;<\/span><span class=\"sy0\">&gt;&lt;\/<\/span>script<span class=\"sy0\">&gt;<\/span><\/div><\/div>\n<div id=\"gantt_here\" style=\"width: 100%; height: 500px;\"><\/div>\n<p><script>\/\/ <![CDATA[\n(function () { \/\/ specifying the date format gantt.config.xml_date = \"%Y-%m-%d %H:%i\"; \/\/ initializing gantt gantt.init(\"gantt_here\"); \/\/ enabling data loading gantt.load(\"\/api\/data\"); \/\/ initializing dataProcessor var dp = new gantt.dataProcessor(\"\/api\/data\/\"); \/\/ and attaching it to gantt dp.init(gantt); \/\/ setting the REST mode for dataProcessor dp.setTransactionMode(\"REST\"); })();\n\/\/ ]]><\/script><\/p>\n<p>In the above code we have done the following:<\/p>\n<ul>\n<li>set a container for the Gantt chart<\/li>\n<li>specified the dates format to load data from the server side<\/li>\n<li>initialized the Gantt chart<\/li>\n<li>enabled data loading<\/li>\n<li>initialized dataProcessor in the REST mode to work with the server side<\/li>\n<\/ul>\n<p>The server side will be implemented a bit later. Now, you can run the application and see that the Gantt chart is rendered on the page:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3834\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/adding_gantt.png\" alt=\"adding_gantt\" width=\"702\" height=\"240\" srcset=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/adding_gantt.png 702w, https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/adding_gantt-300x103.png 300w\" sizes=\"auto, (max-width: 702px) 100vw, 702px\" \/><\/p>\n<h4>Creating Models<\/h4>\n<p>There are two types of data representation in Gantt: <strong>Tasks<\/strong> shown as horizontal bars and <strong>Links<\/strong> between them. Thus, we should create two models.<\/p>\n<h4>Task Model<\/h4>\n<p>Right-click on the <em>Models<\/em> folder to call the context menu and select <em>Add-&gt;Class<\/em>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3828\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/creating_model.png\" alt=\"creating_model\" width=\"690\" height=\"471\" srcset=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/creating_model.png 690w, https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/creating_model-300x205.png 300w\" sizes=\"auto, (max-width: 690px) 100vw, 690px\" \/><\/p>\n<p>Name the created class <em>&#8220;Task&#8221;<\/em>, then open it and add the necessary properties:<\/p>\n<div class=\"codecolorer-container csharp default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"csharp codecolorer\"><span class=\"kw1\">using<\/span> <span class=\"co3\">System<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Collections.Generic<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Linq<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Web<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>namespace gantt_rest_net.Models<br \/>\n{<br \/>\npublic class Task<br \/>\n{<br \/>\npublic int id { get; set; }<br \/>\npublic string text { get; set; }<br \/>\npublic DateTime start_date { get; set; }<br \/>\npublic int duration { get; set; }<br \/>\npublic double progress { get; set; }<br \/>\npublic int parent { get; set; }<br \/>\n}<br \/>\n}<\/p>\n<h4>Link Model<\/h4>\n<p>To create the Link model, create the <em>Link<\/em> class in the <em>Models<\/em> folder and add the following obligatory properties:<\/p>\n<div class=\"codecolorer-container csharp default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"csharp codecolorer\"><span class=\"kw1\">using<\/span> <span class=\"co3\">System<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Collections.Generic<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Linq<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Web<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>namespace gantt_rest_net.Models<br \/>\n{<br \/>\npublic class Link<br \/>\n{<br \/>\npublic int id { get; set; }<br \/>\npublic int source { get; set; }<br \/>\npublic int target { get; set; }<br \/>\npublic string type { get; set; }<br \/>\n}<br \/>\n}<\/p>\n<h3><strong>Step 3. Configure DataBase Connection<\/strong><\/h3>\n<p>As we have mentioned earlier, we&#8217;ll use the Entity Framework for working with the database. To install it, run the following command in the Package Manager Console:<\/p>\n<div class=\"codecolorer-container csharp default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"csharp codecolorer\">Install<span class=\"sy0\">-<\/span>Package EntityFramework<\/div><\/div>\n<p>To use the Entity Framework functionality, we need to apply the following namespace:<\/p>\n<div class=\"codecolorer-container csharp default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"csharp codecolorer\"><span class=\"kw1\">using<\/span> <span class=\"co3\">System.Data.Entity<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<h4>Creating Context<\/h4>\n<p>Context represents a session with the DataBase and allows loading and saving data.<\/p>\n<p>Call the context menu for the <em>Models<\/em> folder and select <em>Add-&gt;Class<\/em>. The new class will be called <em>&#8220;GanttContext&#8221;<\/em> and will have the following content:<\/p>\n<div class=\"codecolorer-container csharp default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"csharp codecolorer\"><span class=\"kw1\">using<\/span> <span class=\"co3\">System<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Collections.Generic<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Data.Entity<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Linq<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Web<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>namespace gantt_rest_net.Models<br \/>\n{<br \/>\npublic class GanttContext: DbContext<br \/>\n{<br \/>\npublic DbSet Tasks { get; set; }<br \/>\npublic DbSet Links { get; set; }<br \/>\n}<br \/>\n}<\/p>\n<h4>Adding Records to Database<\/h4>\n<p>The Entity Framework can automatically create a database when application runs. We should specify that a database should be dropped and re-created whenever the model changes.<\/p>\n<p>First, we should create a database initializer. To do so, we need to add a new class in the <em>App_Start<\/em> folder that will be inherited from the DropCreateDatabaseIfModelChanges class. Let&#8217;s call it <em>&#8220;GanttContextInitializer&#8221;<\/em>.<\/p>\n<p>In this class we&#8217;ll redefine the Seed() method to add some test data. Then we&#8217;ll add a collection of entities into the context using the AddRange() method.<\/p>\n<p>The full code of the <em>GanttContextInitializer<\/em> class is given below:<\/p>\n<div class=\"codecolorer-container csharp default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"csharp codecolorer\"><span class=\"kw1\">using<\/span> <span class=\"co3\">gantt_rest_net.Models<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Collections.Generic<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Data.Entity<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Linq<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Web<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>namespace gantt_rest_net.App_Start<br \/>\n{<br \/>\npublic class GanttContextInitializer: DropCreateDatabaseIfModelChanges<br \/>\n{<br \/>\nprotected override void Seed(GanttContext context)<br \/>\n{<br \/>\ncontext.Tasks.AddRange(new List<br \/>\n{<br \/>\nnew Task { id = 1, text = &#8220;Test Event 1&#8221;,<br \/>\nstart_date = new DateTime(2016, 5, 26), duration = 4 },<br \/>\nnew Task { id = 2, text = &#8220;Test Event 2&#8221;,<br \/>\nstart_date = new DateTime(2016, 5, 25), duration = 6 },<br \/>\nnew Task { id = 3, text = &#8220;Test Event 3&#8221;,<br \/>\nstart_date = new DateTime(2016, 5, 27), duration = 8 },<br \/>\nnew Task { id = 4, text = &#8220;Test Event 4&#8221;,<br \/>\nstart_date = new DateTime(2016, 5, 31), duration = 2 },<br \/>\nnew Task { id = 5, text = &#8220;Test Event 5&#8221;,<br \/>\nstart_date = new DateTime(2016, 5, 26), duration = 7 },<br \/>\n});<\/p>\n<p>context.Links.AddRange(new List {<br \/>\nnew Link { id = 1, source = 1, target = 4, type = &#8220;0&#8221; },<br \/>\nnew Link { id = 2, source = 3, target = 4, type = &#8220;1&#8221; },<br \/>\n});<br \/>\n}<br \/>\n}<br \/>\n}<\/p>\n<p>&nbsp;<\/p>\n<p>Open the <em>Global.asax<\/em> file. It contains code that runs on the application start.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3830\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/global_asax.png\" alt=\"global_asax\" width=\"416\" height=\"257\" srcset=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/global_asax.png 416w, https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/global_asax-300x185.png 300w\" sizes=\"auto, (max-width: 416px) 100vw, 416px\" \/><\/p>\n<p>Add the necessary namespace and the code line that will set Initializer for our context into <em>theApplication_Start()<\/em> method:<\/p>\n<div class=\"codecolorer-container csharp default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"csharp codecolorer\"><span class=\"kw1\">using<\/span> <span class=\"co3\">System<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Collections.Generic<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Linq<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Web<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Web.Mvc<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Web.Routing<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Web.Security<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Web.SessionState<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Web.Http<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Data.Entity<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">gantt_rest_net.App_Start<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">namespace<\/span> gantt_rest_net<br \/>\n<span class=\"br0\">&#123;<\/span><br \/>\n<span class=\"kw1\">public<\/span> <span class=\"kw4\">class<\/span> Global <span class=\"sy0\">:<\/span> HttpApplication<br \/>\n<span class=\"br0\">&#123;<\/span><br \/>\n<span class=\"kw4\">void<\/span> Application_Start<span class=\"br0\">&#40;<\/span><span class=\"kw4\">object<\/span> sender, EventArgs e<span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"br0\">&#123;<\/span><br \/>\nDatabase<span class=\"sy0\">.<\/span><span class=\"me1\">SetInitializer<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw3\">new<\/span> GanttContextInitializer<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span> AreaRegistration<span class=\"sy0\">.<\/span><span class=\"me1\">RegisterAllAreas<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\nGlobalConfiguration<span class=\"sy0\">.<\/span><span class=\"me1\">Configure<\/span><span class=\"br0\">&#40;<\/span>WebApiConfig<span class=\"sy0\">.<\/span><span class=\"me1\">Register<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\nRouteConfig<span class=\"sy0\">.<\/span><span class=\"me1\">RegisterRoutes<\/span><span class=\"br0\">&#40;<\/span>RouteTable<span class=\"sy0\">.<\/span><span class=\"me1\">Routes<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<h4>Adding Response Helpers<\/h4>\n<p>Helpers will form answers on CRUD requests. Let&#8217;s create the <em>Helpers<\/em> folder and add a class named <em>GanttResponseHelper<\/em>. Place the following code into the newly created class:<\/p>\n<div class=\"codecolorer-container csharp default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"csharp codecolorer\"><span class=\"kw1\">using<\/span> <span class=\"co3\">System<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Collections.Generic<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Linq<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Web<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Web.Http.Results<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>namespace gantt_rest_net.Helpers<br \/>\n{<br \/>\npublic class GanttResponseHelper<br \/>\n{<br \/>\npublic static Dictionary&lt;string, string&gt; GetResult(string action, int? tid)<br \/>\n{<br \/>\nvar res = new Dictionary&lt;string, string&gt;();<br \/>\nres.Add(&#8220;action&#8221;, action);<br \/>\nif (tid != null)<br \/>\nres.Add(&#8220;tid&#8221;, tid.ToString());<br \/>\nreturn res;<br \/>\n}<br \/>\n}<br \/>\n}<\/p>\n<p>The <em>GetResult()<\/em> method will generate an appropriate response for Data Processor according to its parameters. Each response will contain the name of an action.<br \/>\nThere is also an optional parameter <em>tid<\/em>. It will be used for &#8220;insert&#8221; actions when database specifies a new id for the newly inserted entity.<\/p>\n<h3><strong>Step 4. Creating API for Loading and Editing Data<\/strong><\/h3>\n<h4>Adding object containing Gantt data<\/h4>\n<p>Gantt holds both tasks and links within a single object. Let&#8217;s create a controller that will be responsible for the loading tasks and links data into the Gantt chart.<\/p>\n<p>Open a context menu for the <em>Controllers<\/em> folder and select <em>Add -&gt; Controller<\/em>.<\/p>\n<p>Choose the <em>Web API 2 Controller -&gt; Empty<\/em> and call a new controller <em>&#8220;DataController&#8221;<\/em>. Then, fill it with the following code:<\/p>\n<div class=\"codecolorer-container csharp default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"csharp codecolorer\"><span class=\"kw1\">using<\/span> <span class=\"co3\">gantt_rest_net.Models<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Collections.Generic<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Linq<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Net<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Net.Http<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">using<\/span> <span class=\"co3\">System.Web.Http<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>namespace gantt_rest_net.Controllers<br \/>\n{<br \/>\npublic class DataController : ApiController<br \/>\n{<br \/>\nprivate string _dateFormat = &#8220;yyyy-MM-dd HH:mm&#8221;;<br \/>\nprivate GanttContext db = new GanttContext();<\/p>\n<p>[HttpGet]<br \/>\npublic IHttpActionResult Get()<br \/>\n{<br \/>\nvar events = new List<object width=\"300\" height=\"150\">();foreach (var item in db.Tasks){events.Add(new{id = item.id,text = item.text,start_date = item.start_date.ToString(_dateFormat),duration = item.duration,progress = item.progress,parent = item.parent});}            return Json(new { data = events, links = db.Links });}}}This code will create an object with data for a Gantt chart. It will contain a list of events and a list of links. The dates of events should be converted into appropriate strings.<\/p>\n<h4>Task Controller<\/h4>\n<p>Now, let&#8217;s add one more controller named <em>TaskController<\/em>, that will provide CRUD API for the Task.We will describe the logic of each request inside of try-catch blocks to handle any errors that might occur when the database is modified:<\/p>\n<div class=\"codecolorer-container csharp default codecolorer-noborder\" style=\"\"><div class=\"csharp codecolorer\"><span class=\"kw1\">using<\/span> <span class=\"co3\">gantt_rest_net.Helpers<\/span><span class=\"sy0\">;<\/span>using <span class=\"co3\">gantt_rest_net.Models<\/span><span class=\"sy0\">;<\/span>using <span class=\"co3\">System<\/span><span class=\"sy0\">;<\/span>using <span class=\"co3\">System.Collections.Generic<\/span><span class=\"sy0\">;<\/span>using <span class=\"co3\">System.Data.Entity<\/span><span class=\"sy0\">;<\/span>using <span class=\"co3\">System.Data.Entity.Infrastructure<\/span><span class=\"sy0\">;<\/span>using <span class=\"co3\">System.Linq<\/span><span class=\"sy0\">;<\/span>using <span class=\"co3\">System.Net<\/span><span class=\"sy0\">;<\/span>using <span class=\"co3\">System.Net.Http<\/span><span class=\"sy0\">;<\/span>using <span class=\"co3\">System.Web.Http<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>namespace gantt_rest_net.Controllers{public class TaskController : ApiController{private GanttContext db = new GanttContext();[HttpPost]public IHttpActionResult Post(Task task){try{if (ModelState.IsValid){db.Tasks.Add(task);db.SaveChanges();return Json(GanttResponseHelper.GetResult(&#8220;inserted&#8221;, task.id));}}catch (Exception) { }return Json(GanttResponseHelper.GetResult(&#8220;error&#8221;, null));}[HttpDelete]public IHttpActionResult Delete(int id){try{var task = db.Tasks.Find(id);db.Tasks.Remove(task);db.SaveChanges();return Json(GanttResponseHelper.GetResult(&#8220;deleted&#8221;, null));}catch (Exception) { }return Json(GanttResponseHelper.GetResult(&#8220;error&#8221;, null));}[HttpPut]public IHttpActionResult Put(int id, Task task){try{if (ModelState.IsValid){task.id = id;db.Entry(task).State = EntityState.Modified;db.SaveChanges();return Json(GanttResponseHelper.GetResult(&#8220;updated&#8221;, null));}}catch (Exception) { }return Json(GanttResponseHelper.GetResult(&#8220;error&#8221;, null));}}}The code of TaskController includes the following types of requests:<\/p>\n<ul>\n<li>POST request means that a new item needs to be inserted into the database<\/li>\n<li>PUT request updates an existing record<\/li>\n<li>DELETE request goes for deleting<\/li>\n<\/ul>\n<p>The GET request wasn&#8217;t used here, since Gantt loads tasks and links together. A common GET request is described within the DataController code.All actions return a JSON response containing the type of the performed operation or \u201cerror\u201d if something went wrong.Notice that response for the <em>insert<\/em> action also contains a database id of the new record. It will be applied on the client side so that the new item could be mapped to the database entity.<\/p>\n<h4>Link Controller<\/h4>\n<p>We can create the Link controller the same way as the Task controller. It will provide CRUD API for Link and include the code as in:<\/p>\n<div class=\"codecolorer-container csharp default codecolorer-noborder\" style=\"\"><div class=\"csharp codecolorer\"><span class=\"kw1\">using<\/span> <span class=\"co3\">gantt_rest_net.Helpers<\/span><span class=\"sy0\">;<\/span>using <span class=\"co3\">gantt_rest_net.Models<\/span><span class=\"sy0\">;<\/span>using <span class=\"co3\">System<\/span><span class=\"sy0\">;<\/span>using <span class=\"co3\">System.Collections.Generic<\/span><span class=\"sy0\">;<\/span>using <span class=\"co3\">System.Data.Entity<\/span><span class=\"sy0\">;<\/span>using <span class=\"co3\">System.Data.Entity.Infrastructure<\/span><span class=\"sy0\">;<\/span>using <span class=\"co3\">System.Linq<\/span><span class=\"sy0\">;<\/span>using <span class=\"co3\">System.Net<\/span><span class=\"sy0\">;<\/span>using <span class=\"co3\">System.Net.Http<\/span><span class=\"sy0\">;<\/span>using <span class=\"co3\">System.Web.Http<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>namespace gantt_rest_net.Controllers{public class LinkController : ApiController{private GanttContext db = new GanttContext();[HttpPost]public IHttpActionResult Post(Link link){try{if (ModelState.IsValid){db.Links.Add(link);db.SaveChanges();return Json(GanttResponseHelper.GetResult(&#8220;inserted&#8221;, link.id));}}catch (Exception) { }return Json(GanttResponseHelper.GetResult(&#8220;error&#8221;, null));}[HttpDelete]public IHttpActionResult Delete(int id){try{var link = db.Links.Find(id);db.Links.Remove(link);db.SaveChanges();return Json(GanttResponseHelper.GetResult(&#8220;deleted&#8221;, null));}catch (Exception) { }return Json(GanttResponseHelper.GetResult(&#8220;error&#8221;, null));}[HttpPut]public IHttpActionResult Put(int id, Link link){try{if (ModelState.IsValid){link.id = id;db.Entry(link).State = EntityState.Modified;db.SaveChanges();return Json(GanttResponseHelper.GetResult(&#8220;updated&#8221;, null));}}catch (Exception) { }return Json(GanttResponseHelper.GetResult(&#8220;error&#8221;, null));}}}Like in case of TaskController, in the code above we\u2019ve described the following types of requests:<\/p>\n<ul>\n<li>POST request means that a new item should be inserted into the database<\/li>\n<li>PUT request updates an existing record<\/li>\n<li>DELETE request is used for deleting<\/li>\n<\/ul>\n<p>Actions return a JSON response with the type of the operation or &#8220;error&#8221;.<\/p>\n<h4>Configuring Routes for API<\/h4>\n<p>Now we should add custom routes to our controllers. These routes will map incoming requests to specific handlers.Open <em>App_Start -&gt; WebApiConfig<\/em> and add routes for Task, Link, and Data into it.<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/webapiconfig.png\" alt=\"webapiconfig\" width=\"379\" height=\"240\" class=\"aligncenter size-full wp-image-3826\" srcset=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/webapiconfig.png 379w, https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/webapiconfig-300x190.png 300w\" sizes=\"auto, (max-width: 379px) 100vw, 379px\" \/>Pay attention that these routes should be placed before the default route.The resulting code should look similar to this:<\/p>\n<div class=\"codecolorer-container csharp default codecolorer-noborder\" style=\"\"><div class=\"csharp codecolorer\"><span class=\"kw1\">using<\/span> <span class=\"co3\">System<\/span><span class=\"sy0\">;<\/span>using <span class=\"co3\">System.Collections.Generic<\/span><span class=\"sy0\">;<\/span>using <span class=\"co3\">System.Linq<\/span><span class=\"sy0\">;<\/span>using <span class=\"co3\">System.Web.Http<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>namespace gantt_rest_net{public static class WebApiConfig{public static void Register(HttpConfiguration config){config.MapHttpAttributeRoutes();config.Routes.MapHttpRoute(name: &#8220;Task&#8221;,routeTemplate: &#8220;api\/data\/task\/{id}&#8221;,defaults: new { controller = &#8220;Task&#8221;, id = RouteParameter.Optional });config.Routes.MapHttpRoute(name: &#8220;Link&#8221;,routeTemplate: &#8220;api\/data\/link\/{id}&#8221;,defaults: new { controller = &#8220;Link&#8221;, id = RouteParameter.Optional });config.Routes.MapHttpRoute(name: &#8220;Data&#8221;,routeTemplate: &#8220;api\/data&#8221;,defaults: new { controller = &#8220;Data&#8221; });config.Routes.MapHttpRoute(name: &#8220;DefaultApi&#8221;,routeTemplate: &#8220;api\/{controller}\/{id}&#8221;,defaults: new { id = RouteParameter.Optional });}}}The <em>Register()<\/em> method is set in the WebApiConfig class by default, it configures HttpConfiguration and sets API routes. So, we just added the necessary routes into it.Now everything is ready. Run the application and the fully-fledged Gantt should appear on the page:<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/ready_gantt_dotnet.png\" alt=\"ready_gantt_dotnet\" width=\"692\" height=\"400\" class=\"aligncenter size-full wp-image-3835\" srcset=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/ready_gantt_dotnet.png 692w, https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/11\/ready_gantt_dotnet-300x173.png 300w\" sizes=\"auto, (max-width: 692px) 100vw, 692px\" \/>That&#8217;s it. We&#8217;ve created a full-functioned Gantt chart. We have spent more efforts as compared to some of our previous examples, but it is worth it. Keep checking our blog and we&#8217;ll keep providing you with detailed recipes for using our products in different ways.<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/08\/download-gantt-banner.png\" alt=\"download gantt\" width=\"900\" height=\"300\" class=\"aligncenter size-full wp-image-3693\" srcset=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/08\/download-gantt-banner.png 900w, https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/08\/download-gantt-banner-300x100.png 300w, https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2016\/08\/download-gantt-banner-768x256.png 768w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/object><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today, we&#8217;ll talk about creating a Gantt chart application with ASP.NET and REST API on the server-side. We will make use of ASP.NET MVC 5 web platform and Web &#8230;<\/p>\n","protected":false},"author":2,"featured_media":3833,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17,71,1,38],"tags":[33,37,20,14,60],"class_list":["post-3822","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-posts-for-codeproject-com","category-tutorials","category-uncategorized","category-visible","tag-all-posts","tag-asp-net","tag-gantt","tag-tips","tag-integrations-gantt"],"_links":{"self":[{"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts\/3822","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/comments?post=3822"}],"version-history":[{"count":2,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts\/3822\/revisions"}],"predecessor-version":[{"id":13471,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts\/3822\/revisions\/13471"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/media\/3833"}],"wp:attachment":[{"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/media?parent=3822"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/categories?post=3822"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/tags?post=3822"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}