将列表对象传递给 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 上公开您的参数...