Fix: error CS0234: The type or namespace name ‘Helpers’ does not exist in the namespace ‘System.Web’, when using multiple virtual IIS web applications

I have a ASP .NET 4.5.2 MVC web application running on an IIS website and I wanted to run a separate ASP .NET 4.5.2. web api application under the MVC web site.

Both projects worked just fine, when hosting them as separate IIS websites, but when the web api was “mounted” as virtual web application under the MVC website I was getting the errors below, when hitting the web api application:

error CS0234: The type or namespace name 'Helpers' does not exist in the namespace 'System.Web' (are you missing an assembly reference?)

error CS0234: The type or namespace name 'Mvc' does not exist in the namespace 'System.Web' (are you missing an assembly reference?)

Line 150:    <pages controlRenderingCompatibilityVersion="4.0">
Line 151:      <namespaces>
Line 152:        <add namespace="System.Web.Helpers" />
Line 153:        <add namespace="System.Web.Mvc" />
Line 154:        <add namespace="System.Web.Mvc.Ajax" />

So I was hitting the web api, but got an error on the parent MVC web application???

Turns out, I had to remove these namespaces in the web api web.config, because those dll’s are not in the web api project.

Adding the following lines to the web.config of the web api project, solved the errors.

<configuration>

<system.web>

<pages controlRenderingCompatibilityVersion="4.0">

      <namespaces>

         <clear/>

      </namespaces>

    </pages>

AngularJS and Breeze – A simple crud app – Part 2 – Adding create, delete, reset and is dirty checking.

 

In my previous post I created a simple [AngularJS – Breeze] edit view. In this post I will add the create, delete, reset and “is dirty” (entity change state tracking) to the simple view.

 

Before create

image

 

Create

The user clicked on the create button, so an “is dirty” icon is shown and a new row is added to the grid.

image

 

Save

When the user fills the fields of the new row and clicks save, the “is dirty” icon will disappear and the id field will automatically be filled by the id generated on the server in the database.

 

image

 

Reset

When the user create, updated and deleted some records and pressed save, the original state of the database can be restored by pressing the reset button.

image

 

 

index.html

<!DOCTYPE html>
<html data-ng-app="app">
<head>
    <title data-ng-bind="title">Angular and Breeze</title>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" />
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />

    <!-- Libraries -->
    <link rel="stylesheet" type="text/css" href="../../../Libraries/FontAwesome/css/font-awesome.min.css" />
    <link rel="stylesheet" type="text/css" href="../../../Libraries/Toastr/toastr.min.css" />
    
    <!-- App -->
    <link rel="stylesheet" type="text/css" href="app.css" />
</head>
<body>
    <div class="spa-page" data-ng-controller="admin as vm">
        <div class="spa-grid-toolbar">
            <a class="spa-action-link" ng-click="vm.save()">save</a> |
            <a class="spa-action-link" ng-click="vm.reset()">reset</a> |
            <a class="spa-action-link" ng-click="vm.create()">create</a>
            <i class="fa fa-exclamation-circle" 
               title="Some data has change. Press save to save the changes to the server!" 
               ng-show="vm.isDirty"></i>
        </div>
        <table class="spa-grid">
            <thead>
                <tr>
                    <th> </th>
                    <th ng-repeat='(key, prop) in vm.entityFields'>{{ prop.name }}</th>
                </tr>
            </thead>
            <tbody>
                <tr ng-repeat="entity in vm.entities">
                    <td><a class="spa-action-link" ng-click="vm.delete(entity)">delete</a></td>
                    <td ng-repeat='(key, prop) in vm.entityFields'>
                        <input ng-disabled="{{vm.isReadOnlyField(prop.name)}}" 
                               type='text' 
                               ng-model='entity[prop.name]'>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>

    <!-- Libraries -->
    <script type="text/javascript" src="../../../Libraries/Angular/angular.js"></script>
    <script type="text/javascript" src="../../../Libraries/Breeze/breeze.debug.js"></script>
    <script type="text/javascript" src="../../../Libraries/Breeze/breeze.angular.js"></script>

    <!-- Add toastr which needs jQuery (Breeze does not need jQuery) -->
    <script type="text/javascript" src="../../../Libraries/jQuery/jquery-2.1.1.js"></script>
    <script type="text/javascript" src="../../../Libraries/Toastr/toastr.js"></script>
    
<!-- Add breeze.savequeuing which needs Q (Breeze does not need Q)--> <script type="text/javascript" src="../../../Libraries/Q/q.min.js"></script> <script type="text/javascript" src="../../../Libraries/Breeze/breeze.savequeuing.js"></script> <!-- App --> <script type="text/javascript" src="app.js"></script> </body> </html>

 

 

app.js

// Use namespaces to prevent pollution of the global namespace.
var spa = spa || {};
spa.controllers = spa.controllers || {};

// Angular module [app].
spa.app = (function () {
    'use strict';

    var app = angular.module('app', [
        'breeze.angular' // The breeze service module.
    ]);
})();

// Angular controller [admin].
spa.controllers.admin = (function () {
    'use strict';
    var controllerId = 'admin';
    angular.module('app').controller(controllerId, ['$http', 'breeze', admin]);

    function admin($http, breeze) {
        var entityChangedToken = null;
        var entityTypeName = "Employee";
        var manager = null;

        var vm = this;
        vm.create = function () {
            // Create entity by breeze.
            var entity = manager.createEntity(entityTypeName);
            // Show entity to user.
            vm.entities.push(entity);
        };
        vm.delete = function (entity) {
            // Delete from UI
            vm.entities.pop(entity);

            // Mark for deletion.
            entity.entityAspect.setDeleted();
        };
        vm.entities = [];
        vm.entityFields = null;
        vm.isDirty = false;
        vm.isReadOnlyField = function (name) {
            // Make 'id' fields read-only.
            return (name === 'id');
        };
        vm.reset = function () {
            // Re-seed database and refetch data.
            $http.get('/breeze/breeze/ReSeed').then(getData).then(handleResetResult).catch(showError);
        };
        vm.save = function () {
            manager.saveChanges().then(handleSaveResult).catch(showError);
        };

        function handleStateChange(args) {
            vm.isDirty = true;
        }

        function getData() {
            // Get entities from the server.
            var query = new breeze.EntityQuery().from(entityTypeName);
            manager.executeQuery(query).then(handleGetDataResult).catch(showError);
        }

        function initialize() {
            // Use camel case for entity properties.
            breeze.NamingConvention.camelCase.setAsDefault();

            // Configure and create EntityManager (double breeze is needed, because of .
            manager = new breeze.EntityManager('/breeze/breeze');
            manager.enableSaveQueuing(true);
            registerForStateChange();

            getData();
        }

        function handleGetDataResult(data) {
            // Get entity fields from metadata.
            var entityMetaData = manager.metadataStore.getEntityType(entityTypeName);
            vm.entityFields = entityMetaData.dataProperties;

            // Show the enties from the server.
            vm.entities = data.results;
            vm.isDirty = false;
        }

        function handleResetResult() {
            vm.isDirty = false;
            toastr.info("Database re-seeded.");
        }

        function handleSaveResult() {
            vm.isDirty = false;
            toastr.info("Changes saved to the server.");
        }

        function registerForStateChange() {
            // Make sure to only subscribe once.
            if (entityChangedToken) { return; }

            // Register for state change.
            entityChangedToken = manager.entityChanged.subscribe(handleStateChange);
        }

        function showError(e) {
            // Show xhr error.
            toastr.error(e);
        }

        initialize();
    }
})();

 

app.css

/* Resets */
html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre,abbr, address, cite, code,
del, dfn, em, img, ins, kbd, q, samp, small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li, fieldset,
form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, 
figcaption, figure, footer, header, hgroup, menu, nav, section, summary, time, mark, audio, video {
    border: 0;              /* Prevent unnecessary white space. */
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    box-sizing: border-box; /*  Border boxing is used, so the padding, margin and borders are within 
                                the width and height of the element. */
    margin: 0;              /* Prevent unnecessary white space. */
    outline: 0;             /* Prevent unnecessary white space. */
    padding: 0;             /* Prevent unnecessary white space. */
    font-size: 100%;
    vertical-align: baseline;
}

html, body {
    height: 100%;       /* Full screen single page app. */
    max-height: 100%;   /* Full screen single page app. */
}

body {
    padding: 20px;
}

a {
    cursor: pointer;
}

a.spa-action-link {
    color: #428bca;
    text-decoration: none;
}

a.spa-action-link:hover, a.spa-action-link:focus {
    color: #2a6496;
    text-decoration: underline;
}

div.spa-page {
    border: 1px solid rgb(212, 212, 212);
    height: 100%;       /* Full screen single page app. */
    max-height: 100%;   /* Full screen single page app. */
    padding: 20px;
    position: relative;
}

div.spa-page > a {
    margin-bottom: 10px;
}

div.spa-grid-toolbar i.fa-exclamation-circle {
    margin-left: 10px;
}

.spa-grid input[type="text"] {
    padding-left: 2px;
}

 

BreezeController.cs

namespace Research.UI.Web.Server.Controllers
{
    using Breeze.ContextProvider;
    using Breeze.ContextProvider.EF6;
    using Breeze.WebApi2;
    using Newtonsoft.Json.Linq;
    using Research.UI.Web.Server.Model;
    using System.Data.Entity.Migrations;
    using System.Linq;
    using System.Web.Http;

    [BreezeController]
    public class BreezeController : ApiController
    {
        private readonly EFContextProvider<ResearchDbContext> _contextProvider;

        public BreezeController(): this(null)
        {
        }

        public BreezeController(EFContextProvider<ResearchDbContext> contextProvider)
        {
            _contextProvider = contextProvider ??  new EFContextProvider<ResearchDbContext>();
        }

        [HttpGet]
        public IQueryable<Employee> Employee()
        {
            return _contextProvider.Context.Employees;
        }

        [HttpGet]
        public string Metadata()
        {
            string result = _contextProvider.Metadata();
            return result;
        }
                        
        [HttpGet]
        public void ReSeed()
        {
            // Remove all records from the "Employees" table.
            _contextProvider.Context.Database.ExecuteSqlCommand("truncate table Employees");

            // Run an "Update-Database" EF migrations command, this will update the database schema 
// to the latest state and run the Seed() method.
var configuration = new Research.UI.Web.Migrations.Configuration(); configuration.ContextType = typeof(ResearchDbContext); var migrator = new DbMigrator(configuration); migrator.Update(); } [HttpPost] public SaveResult SaveChanges(JObject saveBundle) { return _contextProvider.SaveChanges(saveBundle); } } }

 

 

For the complete code, see:

https://github.com/roelvanlisdonk/Research/tree/master/Research/Research.UI.Web/Client/Features/AngularJS_and_Breeze/Part2

AngularJS and Breeze – A simple crud app – Part 1 –Automatic field data binding.

 

I wanted a really simple view in AngularJS, that would allow me to edit the data in a database table.

The view should show a grid containing a row for each record in the database.

Each record should show textboxes (html inputs) for all columns in the database, except the “Id” column.

In this way I could edit all data in a database table.

 

Here’s the end result:

 

image

 

When the user clicks on the “save” button, the data is persisted to the database.

 

image

 

 

Breeze.js

I decided to use Breeze.js for the data interaction.

The main trick I used to automatically data bind the Breeze.js entity data properties (fields) to the UI in AngularJS, is getting the names of the entity data properties (database table column names) from the metadata and then using a ng-repeat to loop over the table records and within this ng-repeat an other ng-repeat to loop over de Breeze entity data properties.

 

Getting table column names with Breeze (part of the client side code):

var entityMetaData = manager.metadataStore.getEntityType(“Employee”);

vm.entityFields = entityMetaData.dataProperties;

Automatically data bind, Breeze entity data properties (part of the client side code):

<tbody> <tr ng-repeat="entity in vm.entities"> <td ng-repeat='(key, prop) in vm.entityFields'>
<input ng-disabled="{{vm.isReadOnlyField(prop.name)}}" type='text' ng-model='entity[prop.name]'>
</
td> </tr> </tbody>

Client side code

<!DOCTYPE html>
<html data-ng-app="app">
<head>
<title data-ng-bind="title">Research page</title>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, 
user-scalable=no" />
<!-- Libraries --> <link rel="stylesheet" type="text/css" href="../../Libraries/Toastr/toastr.min.css" /> <!-- App --> <style> /* Resets */ html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp, small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead,
tr, th, td, article, aside, canvas, details, figcaption, figure, footer, header, hgroup, menu, nav,
section, summary, time, mark, audio, video { border: 0; /* Prevent unnecessary white space. */ -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; /* Padding, margin and borders are within the width and height of the element. */ margin: 0; /* Prevent unnecessary white space. */ outline: 0; /* Prevent unnecessary white space. */ padding: 0; /* Prevent unnecessary white space. */ font-size: 100%; vertical-align: baseline; } html, body { height: 100%; /* Full screen single page app. */ max-height: 100%; /* Full screen single page app. */ } body { padding: 20px; } a { cursor: pointer; } a.spa-action-link { color: #428bca; text-decoration: none; } a.spa-action-link:hover, a.spa-action-link:focus { color: #2a6496; text-decoration: underline; } div.spa-page { border: 1px solid rgb(212, 212, 212); height: 100%; /* Full screen single page app. */ max-height: 100%; /* Full screen single page app. */ padding: 20px; position: relative; } div.spa-page > a { margin-bottom: 10px; } </style> </head> <body> <div class="spa-page" data-ng-controller="admin as vm"> <a class="spa-action-link" ng-click="vm.save()">save</a> <table> <thead> <tr> <th ng-repeat='(key, prop) in vm.entityFields'>{{ prop.name }}</th> </tr> </thead> <tbody> <tr ng-repeat="entity in vm.entities"> <td ng-repeat='(key, prop) in vm.entityFields'>
<
input ng-disabled="{{vm.isReadOnlyField(prop.name)}}"
type='text'
ng-model='entity[prop.name]'>
</
td> </tr> </tbody> </table> </div> <!-- Libraries --> <script type="text/javascript" src="../../Libraries/Angular/angular.js"></script> <script type="text/javascript" src="../../Libraries/Breeze/breeze.debug.js"></script> <script type="text/javascript" src="../../Libraries/Breeze/breeze.angular.js"></script> <!-- Add toastr which needs jQuery (Breeze does not need jQuery) --> <script type="text/javascript" src="../../Libraries/jQuery/jquery-2.1.1.js"></script> <script type="text/javascript" src="../../Libraries/Toastr/toastr.js"></script>
<!-- Add breeze.savequeuing which needs Q (Breeze does not need Q)-->
<script type="text/javascript" src="../../Libraries/Q/q.min.js"></script> <script type="text/javascript" src="../../Libraries/Breeze/breeze.savequeuing.js"></script> <!-- App --> <script type="text/javascript"> // Use namespaces to prevent pollution of the global namespace. var spa = spa || {}; spa.controllers = spa.controllers || {}; // Angular module [app]. spa.app = (function () { 'use strict'; var app = angular.module('app', [ 'breeze.angular' // The breeze service module. ]); })(); // Angular controller [admin]. spa.controllers.admin = (function () { 'use strict'; var controllerId = 'admin'; angular.module('app').controller(controllerId, ['breeze', admin]); function admin(breeze) { var manager = null; var entityTypeName = "Employee"; var vm = this; vm.entities = []; vm.entityFields = null; vm.isReadOnlyField = function (name) { // Make 'id' fields read-only. return (name === 'id'); }; vm.save = function () { manager.saveChanges().then(showInfo).catch(showError); }; function initialize() { // Use camel case for entity properties. breeze.NamingConvention.camelCase.setAsDefault(); // Configure and create EntityManager.
// The first breeze is part of the routing, second breeze is the name of the Web Api
// controller).
manager = new breeze.EntityManager('/breeze/breeze'); manager.enableSaveQueuing(true); // Get entities from the server. var query = new breeze.EntityQuery().from(entityTypeName); manager.executeQuery(query).then(handleRefresh).catch(showError); } function handleRefresh(data) { // Get entity fields from metadata. var entityMetaData = manager.metadataStore.getEntityType(entityTypeName); vm.entityFields = entityMetaData.dataProperties; // Show the enties from the server. vm.entities = data.results; } function showError(e) { // Show xhr error. toastr.error(e); } function showInfo() { // Show info message. toastr.info(entityTypeName + " saved!"); } initialize(); } })(); </script> </body> </html>

 

Sever side code

 

Employee.cs

namespace Research.UI.Web.Server.Model
{
public class Employee
{
    public int Id { get; set; }
    public string FirstName { get; set; }
   public string LastName { get; set; }
  public string PhoneNumber { get; set; }
}
}

ResearchDbContext.cs

namespace Research.UI.Web.Server.Model
{
using System.Collections.Generic;
using System.Data.Entity;
public class ResearchDbContext : DbContext
{
public DbSet<Employee> Employees { get; set; }
}    
}

BreezeWebApiConfig.cs

using System.Web.Http;
[assembly: WebActivator.PreApplicationStartMethod(
typeof(Research.UI.Web.App_Start.BreezeWebApiConfig), "RegisterBreezePreStart")]
namespace Research.UI.Web.App_Start {
///<summary>
/// Inserts the Breeze Web API controller route at the front of all Web API routes
///</summary>
///<remarks>
/// This class is discovered and run during startup; see
/// http://blogs.msdn.com/b/davidebb/archive/2010/10/11/light-up-your-nupacks-with-startup-code-and-webactivator.aspx
///</remarks>
public static class BreezeWebApiConfig {
public static void RegisterBreezePreStart() {
GlobalConfiguration.Configuration.Routes.MapHttpRoute(
name: "BreezeApi",
routeTemplate: "breeze{controller}/{action}"
);
}
}
}

 

BreezeController.cs

namespace Research.UI.Web.Server.Controllers
{
using Breeze.ContextProvider;
using Breeze.ContextProvider.EF6;
using Breeze.WebApi2;
using Newtonsoft.Json.Linq;
using Research.UI.Web.Server.Components;
using Research.UI.Web.Server.Model;
using System.Linq;
using System.Web.Http;
[BreezeController]
public class BreezeController : ApiController
{
private readonly EFContextProvider<ResearchDbContext> _contextProvider;
public BreezeController(): this(null)
{
}
public BreezeController(EFContextProvider<ResearchDbContext> contextProvider)
{
_contextProvider = contextProvider ??  new EFContextProvider<ResearchDbContext>();
}
[HttpGet]
public string Metadata()
{
string result = _contextProvider.Metadata();
return result;
}
[HttpGet]
public IQueryable<Employee> Employee()
{
return _contextProvider.Context.Employees;
}

[HttpPost]
public SaveResult SaveChanges(JObject saveBundle)
{
return _contextProvider.SaveChanges(saveBundle);
}
}
}

POST multiple parameters to an ASP .NET Web Api REST service from a .NET 3.5 assembly, by using one dynamic JObject "options" parameter.

 

Client code in .NET 3.5

 

namespace WordMerge.EndToEndTests
{
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Net;
using Newtonsoft.Json;
[TestClass]
public class UnitTest1
{
[TestMethod]
public void Execute_a_post_request()
{
string url = "http://localhost:63544/api/document";
object result = string.Empty;
// Uses the System.Net.WebClient and not HttpClient, because .NET 2.0 must be supported.
using (var client = new WebClient())
{
// Set the header so it knows we are sending JSON.
client.Headers[HttpRequestHeader.ContentType] = "application/json";
// Create the one and only "options" parameter object.
var dto = new DocumentDto
{
TemplatePath = @"C:\Temp\Templates",
DestinationPath = @"C:\Temp\Destination",
Data = new string[] { "This", " is", " test", " input", " data." }
};
// Serialise the data we are sending in to JSON
string serialisedData = JsonConvert.SerializeObject(dto);
// Make the request
var response = client.UploadString(url, serialisedData);
// Deserialise the response into a GUID
result = JsonConvert.DeserializeObject(response);
}
Assert.AreEqual(@"Succesfully uploaded: This, is, test, input, data.", result.ToString());
}
}
public class DocumentDto
{
public string TemplatePath { get; set; }
public string DestinationPath { get; set; }
public string[] Data { get; set; }
}
}

Server code in .NET 4.5

 

 

namespace Service.api
{
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
public class DocumentController : ApiController
{
// GET api/<controller>
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/<controller>/5
public string Get(int id)
{
return "value";
}
// POST api/<controller>
public string Post([FromBody]JObject jsonData)
{
// Convert the dynamic JObject to a DocumentDto object.
DocumentDto dto = jsonData.ToObject<DocumentDto>();
// Use the given data to create the result.
string seperator = ",";
string data = string.Join(seperator, dto.Data.ToList<string>());
string result = string.Format("Succesfully uploaded: {0}", data);
return result;
}
// PUT api/<controller>/5
public void Put(int id, [FromBody]string value)
{
}
// DELETE api/<controller>/5
public void Delete(int id)
{
}
}
public class DocumentDto
{
public string TemplatePath { get; set; }
public string DestinationPath { get; set; }
public string[] Data { get; set; }
}
}

How to POST a string[] array to a ASP .NET Web Api REST service that uses JSON, from a .NET 2.0 assembly

In this post I will use a UnitTest project written in C# .NET 2.0 as client code.

And a ASP .NET Web Api project as Server (service).

 

Client code

Create a new UnitTest project and change target framework to .net 3.5.

Add nuget package JSON.NET.

 

 

 

 

namespace WordMerge.EndToEndTests
{
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Net;
using Newtonsoft.Json;
[TestClass]
public class UnitTest1
{
[TestMethod]
public void Execute_a_get_request()
{
string url = "http://localhost:63544/api/document";
string result = string.Empty;
// Uses the System.Net.WebClient and not HttpClient, because .NET 2.0 must be supported.
using (var client = new WebClient())
{
// Set the header so it knows we are requesting JSON.
client.Headers[HttpRequestHeader.ContentType] = "application/json";
result = client.DownloadString(url);
}
Assert.AreEqual(@"[""value1"",""value2""]", result);
}
[TestMethod]
public void Execute_a_post_request()
{
string url = "http://localhost:63544/api/document";
object result = string.Empty;
// Uses the System.Net.WebClient and not HttpClient, because .NET 2.0 must be supported.
using (var client = new WebClient())
{
// Set the header so it knows we are sending JSON.
client.Headers[HttpRequestHeader.ContentType] = "application/json";
string[] data = new string[] { "This", " is", " test", " input", " data." };
// Serialise the data we are sending in to JSON
string serialisedData = JsonConvert.SerializeObject(data);
// Make the request
var response = client.UploadString(url, serialisedData);
// Deserialise the response into a GUID
result = JsonConvert.DeserializeObject(response);
}
Assert.AreEqual(@"Succesfully uploaded: This, is, test, input, data.", result.ToString());
}
}
}

NuGet packages config

 

<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="5.0.6" targetFramework="net35" />
</packages>

Server (service) code

Create an empty ASP .NET Web API project in Microsoft Visual Studio 2013.

namespace Service.api
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
public class DocumentController : ApiController
{
// GET api/<controller>
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/<controller>/5
public string Get(int id)
{
return "value";
}
// POST api/<controller>
public string Post([FromBody]string[] values)
{
string seperator = ",";
string data = string.Join(seperator,values.ToList<string>());
string result = string.Format("Succesfully uploaded: {0}", data);
return result;
}
// PUT api/<controller>/5
public void Put(int id, [FromBody]string value)
{
}
// DELETE api/<controller>/5
public void Delete(int id)
{
}
}
}

Visual Studio Structure

image

NuGet packages config

<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.AspNet.WebApi" version="5.0.0-rc1" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.0.0-rc1" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.0.0-rc1" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.0.0-rc1" targetFramework="net45" />
<package id="Newtonsoft.Json" version="4.5.11" targetFramework="net45" />
</packages>