This project has moved. For the latest updates, please go here.
You might have some Web API functions that have object or dynamic object in POST or return, and you may not want to alter the function prototypes for strongly typed interfaces, for the time being and for some reasons. The CodeGen could accommodate such scenarios.

Web API functions:
        [HttpGet]
        [Route("AnonymousDynamic")]
        public dynamic GetAnonymousDynamic()
        {
            return new
            {
                Id = 12345,
                Name = "Something",
            };
        }

        [HttpGet]
        [Route("AnonymousObject")]
        public object GetAnonymousObject()
        {
            return new
            {
                Id = 12345,
                Name = "Something",
            };
        }

        [HttpPost]
        [Route("AnonymousObject")]
        public object PostAnonymousObject([FromBody] dynamic obj)
        {
            if (obj==null)
            {
                System.Diagnostics.Debug.WriteLine("dynamic null");
                return new
                {
                    Id = 12345,
                    Name = "Something",
                };

            }
            obj.Id = obj.Id + "1";
            obj.Name = obj.Name + "1";
            return obj;
        }



Client API C# codes generated:
        /// <summary>
        /// 
        /// GET api/SuperDemo/AnonymousDynamic
        /// </summary>
        public async Task<Newtonsoft.Json.Linq.JObject> GetAnonymousDynamicAsync()
        {
            var template = new System.UriTemplate("api/SuperDemo/AnonymousDynamic");
            var uriParameters = new System.Collections.Specialized.NameValueCollection();
            var requestUri = template.BindByName(this.baseUri, uriParameters);
            var responseMessage = await client.GetAsync(requestUri.ToString());
            responseMessage.EnsureSuccessStatusCode();
            var text = await responseMessage.Content.ReadAsStringAsync();
            return JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JObject>(text);
        }
        
        /// <summary>
        /// 
        /// GET api/SuperDemo/AnonymousDynamic
        /// </summary>
        public Newtonsoft.Json.Linq.JObject GetAnonymousDynamic()
        {
            var template = new System.UriTemplate("api/SuperDemo/AnonymousDynamic");
            var uriParameters = new System.Collections.Specialized.NameValueCollection();
            var requestUri = template.BindByName(this.baseUri, uriParameters);
            var responseMessage = this.client.GetAsync(requestUri.ToString()).Result;
            responseMessage.EnsureSuccessStatusCode();
            var text = responseMessage.Content.ReadAsStringAsync().Result;
            return JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JObject>(text);
        }
        
        /// <summary>
        /// 
        /// GET api/SuperDemo/AnonymousObject
        /// </summary>
        public async Task<Newtonsoft.Json.Linq.JObject> GetAnonymousObjectAsync()
        {
            var template = new System.UriTemplate("api/SuperDemo/AnonymousObject");
            var uriParameters = new System.Collections.Specialized.NameValueCollection();
            var requestUri = template.BindByName(this.baseUri, uriParameters);
            var responseMessage = await client.GetAsync(requestUri.ToString());
            responseMessage.EnsureSuccessStatusCode();
            var text = await responseMessage.Content.ReadAsStringAsync();
            return JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JObject>(text);
        }
        
        /// <summary>
        /// 
        /// GET api/SuperDemo/AnonymousObject
        /// </summary>
        public Newtonsoft.Json.Linq.JObject GetAnonymousObject()
        {
            var template = new System.UriTemplate("api/SuperDemo/AnonymousObject");
            var uriParameters = new System.Collections.Specialized.NameValueCollection();
            var requestUri = template.BindByName(this.baseUri, uriParameters);
            var responseMessage = this.client.GetAsync(requestUri.ToString()).Result;
            responseMessage.EnsureSuccessStatusCode();
            var text = responseMessage.Content.ReadAsStringAsync().Result;
            return JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JObject>(text);
        }
        
        /// <summary>
        /// 
        /// POST api/SuperDemo/AnonymousObject
        /// </summary>
        public async Task<Newtonsoft.Json.Linq.JObject> PostAnonymousObjectAsync(Newtonsoft.Json.Linq.JObject obj)
        {
            var requestUri = new System.Uri(this.baseUri, "api/SuperDemo/AnonymousObject");
            var responseMessage = await client.PostAsJsonAsync(requestUri.ToString(), obj);
            responseMessage.EnsureSuccessStatusCode();
            var text = await responseMessage.Content.ReadAsStringAsync();
            return JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JObject>(text);
        }
        
        /// <summary>
        /// 
        /// POST api/SuperDemo/AnonymousObject
        /// </summary>
        public Newtonsoft.Json.Linq.JObject PostAnonymousObject(Newtonsoft.Json.Linq.JObject obj)
        {
            var requestUri = new System.Uri(this.baseUri, "api/SuperDemo/AnonymousObject");
            var responseMessage = this.client.PostAsJsonAsync(requestUri.ToString(), obj).Result;
            responseMessage.EnsureSuccessStatusCode();
            var text = responseMessage.Content.ReadAsStringAsync().Result;
            return JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JObject>(text);
        }

Client API TypeScript codes generated:
        /** 
         * GET api/SuperDemo/AnonymousDynamic
         * @return {any} 
         */
        GetAnonymousDynamic(callback: (data : any) => any){
            this.httpClient.get(encodeURI(this.baseUri + 'api/SuperDemo/AnonymousDynamic'), callback, this.error, this.statusCode);
        }

        /** 
         * GET api/SuperDemo/AnonymousObject
         * @return {any} 
         */
        GetAnonymousObject(callback: (data : any) => any){
            this.httpClient.get(encodeURI(this.baseUri + 'api/SuperDemo/AnonymousObject'), callback, this.error, this.statusCode);
        }

        /** 
         * POST api/SuperDemo/AnonymousObject
         * @param {any} obj 
         * @return {any} 
         */
        PostAnonymousObject(obj: any, callback: (data : any) => any){
            this.httpClient.post(encodeURI(this.baseUri + 'api/SuperDemo/AnonymousObject'), obj, callback, this.error, this.statusCode);
        }

Client codes consuming the client API:
test("GetAnonymousDynamic", function (assert) {
    var done = assert.async();
    superDemoApi.GetAnonymousDynamic((data) => {
        assert.equal(data.Id, 12345);
        assert.equal(data.Name, "Something");
        done();
    });
});

test("GetAnonymousObject", function (assert) {
    var done = assert.async();
    superDemoApi.GetAnonymousObject((data) => {
        assert.equal(data.Id, 12345);
        assert.equal(data.Name, "Something");
        done();
    });
});

test("PostAnonymousObject", function (assert) {
    var done = assert.async();
    superDemoApi.PostAnonymousObject({ "Id": "12345", "Name": "Something" }, (data) => {
        assert.equal(data.Id, "123451");
        assert.equal(data.Name, "Something1");
        done();
    });
});


Hints:
In many scenarios of dynamic objects, tuple is a good alternative giving you both dynamic creation of object and strongly typed interfaces.

Last edited Dec 23, 2015 at 11:29 PM by zijianhuang, version 2