将列表对象传递给 C# Web Api POST
Pass List object to C# Web Api POST
我正在尝试将列表传递到我的 Web API,但我一直收到空值。在将列表传递给 API 之前,我正在将列表转换为字符串。任何想法如何正确绑定它?
public async Task<ReturnViewModel> ModContactsAsync(List<ContactsDTO> Contacts)
{
ReturnViewModel vm = new ReturnViewModel();
var postContactsUri = new UriBuilder(AppConfig.ServiceUrlBase);
//Converts object into a string
var jsonObject = new JavaScriptSerializer().Serialize(Contacts);
postContactsUri.Path = string.Format(POST_CONTACTS_API_PATH, jsonObject);
//Calls API
var response = await _httpClient.PostAsync(postContactsUri.ToString());
return vm;
}
POST - API CALL 列表产品为空
[HttpPost]
[Route("contacts/Save")]
[ResponseType(typeof(ReturnMessage))]
public async Task<IHttpActionResult> ModContacts([FromBody] List<ContactsDTO> prods)
{
try
{
await Task.Delay(10);
return Ok();
}
catch (Exception ex)
{
throw new PropertyPortalWebApiException(HttpStatusCode.InternalServerError, "Contact information does not exist.", ex);
}
}
是的,它是空的,因为你试图发送一个模型,但在另一个方法中,你试图获取对象列表。
在您的请求将读取之后,您必须获取涉及对象列表的对象。
ModContacts([FromBody] ContactDTO 产品)
在 ContactDTO 中,您必须有一个可序列化的对象列表
public IActionResult GetAllContacts()
{
List<Contacts> contacts = contactService.RetrieveAllContacts();
return Json(contacts);
}
所以理论上以上就是你的API。用户会请求 GetAllContacts
,您将从数据库中获取联系人,然后通过 Json.
return
消费者将编写代码来消费:
var request = CreateWebRequest(url) as HttpWebRequest;
if(request != null)
using(var response = request.GetResponse.GetResponseStream())
var content = Json.DeserializeObject(request.ReadToEnd());
类似上面的内容,应该 return 一个 List<Contacts>
适合你。
我相信这就是你想要做的。
更新:
我注意到您希望消费者保存数据。你会按照这些思路做一些事情:
public IActionResult SaveContact([FromBody] List<Contacts>)
{
// Validate and Save
}
消费者会做 Ajax 或以下几行的事情:
List<Contact> contacts = contactService.GetAllContacts(); // User would have a collection for you.
var post = Json.SerializeObject(contacts);
var request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "POST";
request.ContentType = ...
request.ContentLength = post.Length;
request.UserAgent = ...
request.Accept = ...
request.Referer = ...
using(var writer = new StreamWriter(request.GetRequestStream())
{
writer.Write(post);
request.GetResponse();
request.Close();
}
您不需要我表示的请求的所有参数,但它们存在。希望这有帮助。
我想通了这个问题。只需将 Contacts 对象添加到 PostAsync 的第二个参数即可。您不需要将对象转换为 JSON.
public async Task<ReturnViewModel> ModContactsAsync(List<ContactsDTO> Contacts)
{
ReturnViewModel vm = new ReturnViewModel();
var postContactsUri = new UriBuilder(AppConfig.ServiceUrlBase);
postContactsUri.Path = string.Format(POST_CONTACTS_API_PATH, jsonObject);
//Add Contacts to second parameter
var response = await _httpClient.PostAsync(postContactsUri.ToString(), Contacts);
return vm;
}
您应该简单地搜索并了解 GET/POST 区别以及如何 post 使用 HttpClient。
首先,您要在 URL 中添加您的内容,并尝试使用 HttpClient post 它。
var response = await _httpClient.PostAsync(postContactsUri.ToString());
然后在您的 API 中,您正在读取已传入 URL 的对象 FromBody。
public async Task<IHttpActionResult> ModContacts([FromBody] List<ContactsDTO> prods)
PostAsync 方法的签名是
public Task PostAsync(Uri uri, HttpContent content)
所以你应该在第一个参数中传递 URL 并且你的列表对象以 HttpContent 的形式作为第二个参数。
或者您可以使用 PostAsJsonAsync 扩展方法。
解决了我的案例(解决方案 here)。
基本上:
public async Task<ReturnViewModel> ModContactsAsync(List<ContactsDTO> Contacts)
{
ReturnViewModel vm = new ReturnViewModel();
var bodyContent = JsonConvert.SerializeObject(Contacts);
using (var client = new HttpClient())
{
var response = await client.PostAsync(AppConfig.ServiceUrlBase, new StringContent(bodyContent, Encoding.UTF8, "application/json"));
return responseString.Result.Content.ReadAsStringAsync().Result;
}
return vm;
}
您已经从之前的评论中了解到,客户端无法将列表作为查询参数发送,而服务器希望它出现在正文中。
使用上面的代码,客户端在body中发送列表,服务器从body中读取它。
从不 发送列表作为查询参数,即使它是一个小列表。
URL 长度有限制,如果 POST 方法允许您使用请求正文发送信息,为什么还要在 URL 上公开您的参数...
我正在尝试将列表传递到我的 Web API,但我一直收到空值。在将列表传递给 API 之前,我正在将列表转换为字符串。任何想法如何正确绑定它?
public async Task<ReturnViewModel> ModContactsAsync(List<ContactsDTO> Contacts)
{
ReturnViewModel vm = new ReturnViewModel();
var postContactsUri = new UriBuilder(AppConfig.ServiceUrlBase);
//Converts object into a string
var jsonObject = new JavaScriptSerializer().Serialize(Contacts);
postContactsUri.Path = string.Format(POST_CONTACTS_API_PATH, jsonObject);
//Calls API
var response = await _httpClient.PostAsync(postContactsUri.ToString());
return vm;
}
POST - API CALL 列表产品为空
[HttpPost]
[Route("contacts/Save")]
[ResponseType(typeof(ReturnMessage))]
public async Task<IHttpActionResult> ModContacts([FromBody] List<ContactsDTO> prods)
{
try
{
await Task.Delay(10);
return Ok();
}
catch (Exception ex)
{
throw new PropertyPortalWebApiException(HttpStatusCode.InternalServerError, "Contact information does not exist.", ex);
}
}
是的,它是空的,因为你试图发送一个模型,但在另一个方法中,你试图获取对象列表。 在您的请求将读取之后,您必须获取涉及对象列表的对象。
ModContacts([FromBody] ContactDTO 产品)
在 ContactDTO 中,您必须有一个可序列化的对象列表
public IActionResult GetAllContacts()
{
List<Contacts> contacts = contactService.RetrieveAllContacts();
return Json(contacts);
}
所以理论上以上就是你的API。用户会请求 GetAllContacts
,您将从数据库中获取联系人,然后通过 Json.
消费者将编写代码来消费:
var request = CreateWebRequest(url) as HttpWebRequest;
if(request != null)
using(var response = request.GetResponse.GetResponseStream())
var content = Json.DeserializeObject(request.ReadToEnd());
类似上面的内容,应该 return 一个 List<Contacts>
适合你。
我相信这就是你想要做的。
更新:
我注意到您希望消费者保存数据。你会按照这些思路做一些事情:
public IActionResult SaveContact([FromBody] List<Contacts>)
{
// Validate and Save
}
消费者会做 Ajax 或以下几行的事情:
List<Contact> contacts = contactService.GetAllContacts(); // User would have a collection for you.
var post = Json.SerializeObject(contacts);
var request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "POST";
request.ContentType = ...
request.ContentLength = post.Length;
request.UserAgent = ...
request.Accept = ...
request.Referer = ...
using(var writer = new StreamWriter(request.GetRequestStream())
{
writer.Write(post);
request.GetResponse();
request.Close();
}
您不需要我表示的请求的所有参数,但它们存在。希望这有帮助。
我想通了这个问题。只需将 Contacts 对象添加到 PostAsync 的第二个参数即可。您不需要将对象转换为 JSON.
public async Task<ReturnViewModel> ModContactsAsync(List<ContactsDTO> Contacts)
{
ReturnViewModel vm = new ReturnViewModel();
var postContactsUri = new UriBuilder(AppConfig.ServiceUrlBase);
postContactsUri.Path = string.Format(POST_CONTACTS_API_PATH, jsonObject);
//Add Contacts to second parameter
var response = await _httpClient.PostAsync(postContactsUri.ToString(), Contacts);
return vm;
}
您应该简单地搜索并了解 GET/POST 区别以及如何 post 使用 HttpClient。
首先,您要在 URL 中添加您的内容,并尝试使用 HttpClient post 它。
var response = await _httpClient.PostAsync(postContactsUri.ToString());
然后在您的 API 中,您正在读取已传入 URL 的对象 FromBody。
public async Task<IHttpActionResult> ModContacts([FromBody] List<ContactsDTO> prods)
PostAsync 方法的签名是
public Task PostAsync(Uri uri, HttpContent content)
所以你应该在第一个参数中传递 URL 并且你的列表对象以 HttpContent 的形式作为第二个参数。
或者您可以使用 PostAsJsonAsync 扩展方法。
解决了我的案例(解决方案 here)。
基本上:
public async Task<ReturnViewModel> ModContactsAsync(List<ContactsDTO> Contacts)
{
ReturnViewModel vm = new ReturnViewModel();
var bodyContent = JsonConvert.SerializeObject(Contacts);
using (var client = new HttpClient())
{
var response = await client.PostAsync(AppConfig.ServiceUrlBase, new StringContent(bodyContent, Encoding.UTF8, "application/json"));
return responseString.Result.Content.ReadAsStringAsync().Result;
}
return vm;
}
您已经从之前的评论中了解到,客户端无法将列表作为查询参数发送,而服务器希望它出现在正文中。
使用上面的代码,客户端在body中发送列表,服务器从body中读取它。
从不 发送列表作为查询参数,即使它是一个小列表。 URL 长度有限制,如果 POST 方法允许您使用请求正文发送信息,为什么还要在 URL 上公开您的参数...