C# 如何使用C将复杂的类对象传递给Web API#
我需要在没有AJAX或jQuery的情况下,将复杂或列表类对象传递给C#中的web API。这是我用于API和控制器的代码 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
[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)
{
}
}
}
}