C# 如何使用C将复杂的类对象传递给Web API#

C# 如何使用C将复杂的类对象传递给Web API#,c#,asp.net-mvc-4,asp.net-web-api,C#,Asp.net Mvc 4,Asp.net Web Api,我需要在没有AJAX或jQuery的情况下,将复杂或列表类对象传递给C#中的web API。这是我用于API和控制器的代码 Web API: [AcceptVerbs("GET", "POST")] [HttpGet] public void WriteBusinessObjectApiFromObj(int Pa1, string Pa2, object item) { // To Do In Function } 控制器: pub

我需要在没有AJAX或jQuery的情况下,将复杂或列表类对象传递给C#中的web API。这是我用于API和控制器的代码

Web API:

[AcceptVerbs("GET", "POST")]
[HttpGet]
public void WriteBusinessObjectApiFromObj(int Pa1, string Pa2, object item)
        {
            // To Do In Function 
        }
控制器:

 public void WriteBusinessObjectApi(object obj)
        {


            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri("http://localhost:8080/");
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                var apiUrl = "api/WriteBusinessObjectApiFromObj?Pa1=1&Pa2=2";
                var response = client.PostAsJsonAsync(apiUrl, obj).Result;
                client.Dispose();
                if (response.IsSuccessStatusCode)
                {
                }
            }

        }
我尝试调用API,但无法向其发送对象

我尝试发送的此对象如下:

从此函数返回的对象列表:

public List<Product> GetProductsObj()
        {
            var products = new List<Product>
            {
                new Product()
                {
                    Id = 4,
                    Name = "product 4",
                    SupProducts = new List<SupProduct>
                    {
                        new SupProduct()
                        {
                            Id = 41,
                            Name = "Sup 41"
                        },
                        new SupProduct()
                        {
                            Id = 42,
                            Name = "Sup 42"
                        },
                        new SupProduct()
                        {
                            Id = 43,
                            Name = "Sup 43"
                        }
                    }
                },
                new Product()
                {
                    Id = 5,
                    Name = "product 5",
                    SupProducts = new List<SupProduct>
                    {
                        new SupProduct()
                        {
                            Id = 51,
                            Name = "Sup 51"
                        },
                        new SupProduct()
                        {
                            Id = 52,
                            Name = "Sup 52"
                        },
                        new SupProduct()
                        {
                            Id = 53,
                            Name = "Sup 53"
                        }
                    }
                },
                new Product()
                {
                    Id = 6,
                    Name = "product 6",
                    SupProducts = new List<SupProduct>
                    {
                        new SupProduct()
                        {
                            Id = 71,
                            Name = "Sup 71"
                        },
                        new SupProduct()
                        {
                            Id = 72,
                            Name = "Sup 72"
                        },
                        new SupProduct()
                        {
                            Id = 73,
                            Name = "Sup 73"
                        }
                    }
                }
            };
            return products;
        }
public List GetProductsObj()
{
var产品=新列表
{
新产品()
{
Id=4,
Name=“产品4”,
SupProducts=新列表
{
新SupProduct()
{
Id=41,
Name=“Sup 41”
},
新SupProduct()
{
Id=42,
Name=“Sup 42”
},
新SupProduct()
{
Id=43,
Name=“Sup 43”
}
}
},
新产品()
{
Id=5,
Name=“产品5”,
SupProducts=新列表
{
新SupProduct()
{
Id=51,
Name=“Sup 51”
},
新SupProduct()
{
Id=52,
Name=“Sup 52”
},
新SupProduct()
{
Id=53,
Name=“Sup 53”
}
}
},
新产品()
{
Id=6,
Name=“产品6”,
SupProducts=新列表
{
新SupProduct()
{
Id=71,
Name=“Sup 71”
},
新SupProduct()
{
Id=72,
Name=“Sup 72”
},
新SupProduct()
{
Id=73,
Name=“Sup 73”
}
}
}
};
退货产品;
}

绑定器可能会混淆,并试图错误地混合FromBody和FromURI,因此请尝试将所有参数包装到一个对象中。无论如何,这是一个更好的模式,因为您要明确说明发出“请求”的是什么。还要注意,在下面的示例中,我指定了对象类型,而不仅仅是说“object”。最好是明确的,你知道两边的类型

public class WriteBusinessObjectApiFromObjRequest
{
    public int Pa1 { get; set; }
    public string Pa2 { get; set; }
    public List<Product> Item { get; set; } // change to your Type
}

[AcceptVerbs("GET", "POST")]
[HttpGet]
public void WriteBusinessObjectApiFromObj(WriteBusinessObjectApiFromObjRequest request)
{
    // To Do In Function 
}

var apiUrl = "api/WriteBusinessObjectApiFromObj";
var response = client.PostAsJsonAsync(
     apiUrl, 
     new WriteBusinessObjectApiFromObj { Pa1 = 1, Pa2 = "2", Item = obj })
     .Result;
公共类WriteBusinessObjectApiFromObjRequest
{
公共int Pa1{get;set;}
公共字符串Pa2{get;set;}
公共列表项{get;set;}//更改为您的类型
}
[接受动词(“获取”、“发布”)]
[HttpGet]
public void WriteBusinessObjectApiFromObj(WriteBusinessObjectApiFromObjRequest请求)
{
//履行职能
}
var apiUrl=“api/WriteBusinessObjectApiFromObj”;
var response=client.PostAsJsonAsync(
阿皮乌尔,
新的WriteBusinessObjectApiFromObj{Pa1=1,Pa2=“2”,Item=obj})
.结果;
下面是一个没有涉及任何技术细节的示例。或者,这里是一个

模型:

public class Employee
{
    [Required]
    public string EmployeeId { get; set; }

    public string EmployeeName { get; set; }

    public int EmployeeRollNum { get; set; }

    public EmployeeAddress EmployeeAddr { get; set; }

    public List<EmployeeAddress> AllEmployeeAddr { get; set; }
}

public class EmployeeAddress
{
    //[Required]
    public string EmployeeAddressId { get; set; }

    public string EmployeeAddressName { get; set; }

    public List<int> AllNum { get; set; }
}
在Web Api客户端中:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

namespace WebApiConsoleApplication1
{
    public static class UrlHelpers
    {
        /// <summary>
        /// To the query string. http://ole.michelsen.dk/blog/serialize-object-into-a-query-string-with-reflection.html 
        /// </summary>
        /// <param name="request"> The request. </param>
        /// <param name="separator"> The separator. </param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException"> request </exception>
        public static string ToQueryString(this object request, string innerPropertyName = null, string separator = ",")
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            StringBuilder propertyQuery = new StringBuilder();

            // Get all primitive properties on the object 
            var properties = request.GetType().GetProperties()
                .Where(x => x.CanRead)
                .Where(x => x.GetValue(request, null) != null)
                .Where(x => !x.PropertyType.IsClass || (x.PropertyType.IsClass && x.PropertyType.FullName == "System.String"))
                .ToDictionary(x => x.Name, x => x.GetValue(request, null));

            foreach (KeyValuePair<string, object> kvp in properties)
            {
                if (string.IsNullOrEmpty(innerPropertyName))
                {
                    propertyQuery.AppendFormat("{0}={1}", Uri.EscapeDataString(kvp.Key), Uri.EscapeDataString(kvp.Value.ToString()));
                }
                else
                {
                    propertyQuery.AppendFormat("{0}.{1}={2}", Uri.EscapeDataString(innerPropertyName), Uri.EscapeDataString(kvp.Key), Uri.EscapeDataString(kvp.Value.ToString()));
                }
                propertyQuery.AppendFormat("&");
            }

            var innerClass = request.GetType().GetProperties()
                .Where(x => x.CanRead)
                .Where(x => x.GetValue(request, null) != null && x.PropertyType.IsClass && x.PropertyType.FullName != "System.String" && !(x.GetValue(request, null) is IEnumerable))
                .ToDictionary(x => x.Name, x => x.GetValue(request, null));

            // Get names for all IEnumerable properties (excl. string) 
            var propertyCollectionNames = request.GetType().GetProperties()
                .Where(x => x.CanRead)
                .Where(x => x.GetValue(request, null) != null)
                .ToDictionary(x => x.Name, x => x.GetValue(request, null))
                .Where(x => !(x.Value is string) && x.Value is IEnumerable)
                .ToDictionary(x => x.Key, x => x.Value);

            // Concat all IEnumerable properties into a comma separated string 
            foreach (var kvp in propertyCollectionNames)
            {
                var valueType = kvp.Value.GetType();
                var valueElemType = valueType.IsGenericType
                                        ? valueType.GetGenericArguments()[0]
                                        : valueType.GetElementType();
                if (valueElemType.IsPrimitive || valueElemType == typeof(string)) // List of primitive value type or string
                {
                    var enumerable = kvp.Value as IEnumerable;
                    int count = 0;
                    foreach (object obj in enumerable)
                    {
                        if (string.IsNullOrEmpty(innerPropertyName))
                        {
                            propertyQuery.AppendFormat("{0}[{1}]={2}", Uri.EscapeDataString(kvp.Key), count, Uri.EscapeDataString(obj.ToString()));
                        }
                        else
                        {
                            propertyQuery.AppendFormat("{0}.{1}[{2}]={3}", Uri.EscapeDataString(innerPropertyName), Uri.EscapeDataString(kvp.Key), count, Uri.EscapeDataString(obj.ToString()));
                        }
                        count++;
                        propertyQuery.AppendFormat("&");
                    }
                }
                else if (valueElemType.IsClass) // list of class Objects
                {
                    int count = 0;
                    foreach (var className in kvp.Value as IEnumerable)
                    {
                        string queryKey = string.Format("{0}[{1}]", kvp.Key, count);
                        propertyQuery.AppendFormat(ToQueryString(className, queryKey));
                        count++;
                    }
                }
            }

            foreach (var className in innerClass)
            {
                propertyQuery.AppendFormat(ToQueryString(className.Value, className.Key));
            }

            return propertyQuery.ToString();
        }
    }

    public class Employee
    {
        public string EmployeeId { get; set; }

        public string EmployeeName { get; set; }

        public int EmployeeRollNum { get; set; }

        public EmployeeAddress EmployeeAddr { get; set; }

        public List<EmployeeAddress> AllEmployeeAddr { get; set; }
    }

    public class EmployeeAddress
    {
        //[Required]
        public string EmployeeAddressId { get; set; }

        public string EmployeeAddressName { get; set; }

        public List<int> AllNum { get; set; }
    }

    internal class Program
    {
        private static void Main()
        {
            RunAsync().Wait();
            Console.WriteLine("Completed");
            Console.ReadLine();
        }

        private static async Task RunAsync()
        {
            try
            {
                using (var client = new HttpClient())
                {
                    client.BaseAddress = new Uri(ConfigurationManager.AppSettings.Get("HostURL"));
                    client.DefaultRequestHeaders.Accept.Clear();
                    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(ConfigurationManager.AppSettings.Get("AcceptType")));

                    HttpResponseMessage response = await client.GetAsync("api/Values/1");
                    if (response.IsSuccessStatusCode)
                    {
                        string val = await response.Content.ReadAsAsync<string>();
                        Console.WriteLine("{0}\t", val);
                    }

                    client.DefaultRequestHeaders.Accept.Clear();
                    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(ConfigurationManager.AppSettings.Get("AcceptType")));

                    //client.DefaultRequestHeaders.Add()
                    // HTTP GET
                    Employee emp = new Employee();
                    emp.EmployeeId = "sri1";

                    emp.AllEmployeeAddr = new List<EmployeeAddress>();
                    EmployeeAddress lstemployeeAddr = new EmployeeAddress();
                    lstemployeeAddr.EmployeeAddressId = "Address1";

                    lstemployeeAddr.AllNum = new List<int>();
                    lstemployeeAddr.AllNum.Add(1);
                    lstemployeeAddr.AllNum.Add(2);
                    lstemployeeAddr.AllNum.Add(3);
                    emp.AllEmployeeAddr.Add(lstemployeeAddr);

                    lstemployeeAddr = new EmployeeAddress();
                    lstemployeeAddr.EmployeeAddressId = "Address2";
                    lstemployeeAddr.AllNum = new List<int>();
                    lstemployeeAddr.AllNum.Add(24);
                    lstemployeeAddr.AllNum.Add(56);
                    emp.AllEmployeeAddr.Add(lstemployeeAddr);

                    EmployeeAddress innerEmployeeAddr = new EmployeeAddress();
                    innerEmployeeAddr.EmployeeAddressId = "Addr3";
                    innerEmployeeAddr.AllNum = new List<int>();
                    innerEmployeeAddr.AllNum.Add(5);
                    innerEmployeeAddr.AllNum.Add(6);
                    emp.EmployeeAddr = innerEmployeeAddr;

                    string query = emp.ToQueryString();

                    response = await client.GetAsync("api/Values?" + query);
                    if (response.IsSuccessStatusCode)
                    {
                        Employee product = await response.Content.ReadAsAsync<Employee>();
                        Console.WriteLine("{0}\t{1}\t", product.EmployeeId, product.EmployeeName);
                    }
                }
            }
            catch (Exception ex)
            {
            }
        }
    }
}
使用系统;
使用系统集合;
使用System.Collections.Generic;
使用系统配置;
使用System.Linq;
使用System.Net.Http;
使用System.Net.Http.Header;
使用系统文本;
使用System.Threading.Tasks;
命名空间WebApiConsoleApplication1
{
公共静态类UrlHelpers
{
/// 
///添加到查询字符串。http://ole.michelsen.dk/blog/serialize-object-into-a-query-string-with-reflection.html 
/// 
///请求。
///分离器。
/// 
///请求
公共静态字符串ToQueryString(此对象请求,字符串innerPropertyName=null,字符串分隔符=“,”)
{
if(请求==null)
{
抛出新的ArgumentNullException(“请求”);
}
StringBuilder propertyQuery=新建StringBuilder();
//获取对象上的所有基元属性
var properties=request.GetType().GetProperties()
.其中(x=>x.CanRead)
.Where(x=>x.GetValue(请求,null)!=null)
.Where(x=>!x.PropertyType.IsClass | | |(x.PropertyType.IsClass&&x.PropertyType.FullName==“System.String”))
.ToDictionary(x=>x.Name,x=>x.GetValue(请求,null));
foreach(属性中的KeyValuePair kvp)
{
if(string.IsNullOrEmpty(innerPropertyName))
{
propertyQuery.AppendFormat(“{0}={1}”、Uri.EscapeDataString(kvp.Key)、Uri.EscapeDataString(kvp.Value.ToString());
}
其他的
{
propertyQuery.AppendFormat(“{0}.{1}={2}”、Uri.EscapeDataString(innerPropertyName)、Uri.EscapeDataString(kvp.Key)、Uri.EscapeDataString(kvp.Value.ToString());
}
AppendFormat(“&”);
}
var innerClass=request.GetType().GetProperties()
.其中(x=>x.CanRead)
.Where(x=>x.GetValue(request,null)!=null&&x.PropertyType.IsClass&&
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

namespace WebApiConsoleApplication1
{
    public static class UrlHelpers
    {
        /// <summary>
        /// To the query string. http://ole.michelsen.dk/blog/serialize-object-into-a-query-string-with-reflection.html 
        /// </summary>
        /// <param name="request"> The request. </param>
        /// <param name="separator"> The separator. </param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException"> request </exception>
        public static string ToQueryString(this object request, string innerPropertyName = null, string separator = ",")
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            StringBuilder propertyQuery = new StringBuilder();

            // Get all primitive properties on the object 
            var properties = request.GetType().GetProperties()
                .Where(x => x.CanRead)
                .Where(x => x.GetValue(request, null) != null)
                .Where(x => !x.PropertyType.IsClass || (x.PropertyType.IsClass && x.PropertyType.FullName == "System.String"))
                .ToDictionary(x => x.Name, x => x.GetValue(request, null));

            foreach (KeyValuePair<string, object> kvp in properties)
            {
                if (string.IsNullOrEmpty(innerPropertyName))
                {
                    propertyQuery.AppendFormat("{0}={1}", Uri.EscapeDataString(kvp.Key), Uri.EscapeDataString(kvp.Value.ToString()));
                }
                else
                {
                    propertyQuery.AppendFormat("{0}.{1}={2}", Uri.EscapeDataString(innerPropertyName), Uri.EscapeDataString(kvp.Key), Uri.EscapeDataString(kvp.Value.ToString()));
                }
                propertyQuery.AppendFormat("&");
            }

            var innerClass = request.GetType().GetProperties()
                .Where(x => x.CanRead)
                .Where(x => x.GetValue(request, null) != null && x.PropertyType.IsClass && x.PropertyType.FullName != "System.String" && !(x.GetValue(request, null) is IEnumerable))
                .ToDictionary(x => x.Name, x => x.GetValue(request, null));

            // Get names for all IEnumerable properties (excl. string) 
            var propertyCollectionNames = request.GetType().GetProperties()
                .Where(x => x.CanRead)
                .Where(x => x.GetValue(request, null) != null)
                .ToDictionary(x => x.Name, x => x.GetValue(request, null))
                .Where(x => !(x.Value is string) && x.Value is IEnumerable)
                .ToDictionary(x => x.Key, x => x.Value);

            // Concat all IEnumerable properties into a comma separated string 
            foreach (var kvp in propertyCollectionNames)
            {
                var valueType = kvp.Value.GetType();
                var valueElemType = valueType.IsGenericType
                                        ? valueType.GetGenericArguments()[0]
                                        : valueType.GetElementType();
                if (valueElemType.IsPrimitive || valueElemType == typeof(string)) // List of primitive value type or string
                {
                    var enumerable = kvp.Value as IEnumerable;
                    int count = 0;
                    foreach (object obj in enumerable)
                    {
                        if (string.IsNullOrEmpty(innerPropertyName))
                        {
                            propertyQuery.AppendFormat("{0}[{1}]={2}", Uri.EscapeDataString(kvp.Key), count, Uri.EscapeDataString(obj.ToString()));
                        }
                        else
                        {
                            propertyQuery.AppendFormat("{0}.{1}[{2}]={3}", Uri.EscapeDataString(innerPropertyName), Uri.EscapeDataString(kvp.Key), count, Uri.EscapeDataString(obj.ToString()));
                        }
                        count++;
                        propertyQuery.AppendFormat("&");
                    }
                }
                else if (valueElemType.IsClass) // list of class Objects
                {
                    int count = 0;
                    foreach (var className in kvp.Value as IEnumerable)
                    {
                        string queryKey = string.Format("{0}[{1}]", kvp.Key, count);
                        propertyQuery.AppendFormat(ToQueryString(className, queryKey));
                        count++;
                    }
                }
            }

            foreach (var className in innerClass)
            {
                propertyQuery.AppendFormat(ToQueryString(className.Value, className.Key));
            }

            return propertyQuery.ToString();
        }
    }

    public class Employee
    {
        public string EmployeeId { get; set; }

        public string EmployeeName { get; set; }

        public int EmployeeRollNum { get; set; }

        public EmployeeAddress EmployeeAddr { get; set; }

        public List<EmployeeAddress> AllEmployeeAddr { get; set; }
    }

    public class EmployeeAddress
    {
        //[Required]
        public string EmployeeAddressId { get; set; }

        public string EmployeeAddressName { get; set; }

        public List<int> AllNum { get; set; }
    }

    internal class Program
    {
        private static void Main()
        {
            RunAsync().Wait();
            Console.WriteLine("Completed");
            Console.ReadLine();
        }

        private static async Task RunAsync()
        {
            try
            {
                using (var client = new HttpClient())
                {
                    client.BaseAddress = new Uri(ConfigurationManager.AppSettings.Get("HostURL"));
                    client.DefaultRequestHeaders.Accept.Clear();
                    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(ConfigurationManager.AppSettings.Get("AcceptType")));

                    HttpResponseMessage response = await client.GetAsync("api/Values/1");
                    if (response.IsSuccessStatusCode)
                    {
                        string val = await response.Content.ReadAsAsync<string>();
                        Console.WriteLine("{0}\t", val);
                    }

                    client.DefaultRequestHeaders.Accept.Clear();
                    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(ConfigurationManager.AppSettings.Get("AcceptType")));

                    //client.DefaultRequestHeaders.Add()
                    // HTTP GET
                    Employee emp = new Employee();
                    emp.EmployeeId = "sri1";

                    emp.AllEmployeeAddr = new List<EmployeeAddress>();
                    EmployeeAddress lstemployeeAddr = new EmployeeAddress();
                    lstemployeeAddr.EmployeeAddressId = "Address1";

                    lstemployeeAddr.AllNum = new List<int>();
                    lstemployeeAddr.AllNum.Add(1);
                    lstemployeeAddr.AllNum.Add(2);
                    lstemployeeAddr.AllNum.Add(3);
                    emp.AllEmployeeAddr.Add(lstemployeeAddr);

                    lstemployeeAddr = new EmployeeAddress();
                    lstemployeeAddr.EmployeeAddressId = "Address2";
                    lstemployeeAddr.AllNum = new List<int>();
                    lstemployeeAddr.AllNum.Add(24);
                    lstemployeeAddr.AllNum.Add(56);
                    emp.AllEmployeeAddr.Add(lstemployeeAddr);

                    EmployeeAddress innerEmployeeAddr = new EmployeeAddress();
                    innerEmployeeAddr.EmployeeAddressId = "Addr3";
                    innerEmployeeAddr.AllNum = new List<int>();
                    innerEmployeeAddr.AllNum.Add(5);
                    innerEmployeeAddr.AllNum.Add(6);
                    emp.EmployeeAddr = innerEmployeeAddr;

                    string query = emp.ToQueryString();

                    response = await client.GetAsync("api/Values?" + query);
                    if (response.IsSuccessStatusCode)
                    {
                        Employee product = await response.Content.ReadAsAsync<Employee>();
                        Console.WriteLine("{0}\t{1}\t", product.EmployeeId, product.EmployeeName);
                    }
                }
            }
            catch (Exception ex)
            {
            }
        }
    }
}