将List对象传递给C#Web Api POST

时间:2017-11-28 15:59:55

标签: c# asp.net-mvc asp.net-web-api asp.net-web-api2 asp.net-web-api-routing

我正在尝试将List传递给我的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 List prod为null

[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);
    }
  }

5 个答案:

答案 0 :(得分:0)

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());

如上所述,应该为您返回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();
}

您不需要我所表示的请求的所有参数,但它们存在。希望这会有所帮助。

答案 1 :(得分:0)

我想出了这个问题。只需将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;

}

答案 2 :(得分:0)

您应该只搜索并了解GET / POST差异以及如何使用HttpClient发布。

首先,您要在网址中添加内容并尝试使用HttpClient发布。

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扩展方法。

答案 3 :(得分:0)

解决了与您的案件相似的我的案件(解决方案here)。

基本上:

val reducedRdd = rdd.mapPartitions(partition => partition.map(r => (r.id, r)))
//val reducedRdd = rdd.map(r => (r.id, r))
.reduceByKey((r1, r2) => r1.combineElem(r2))
// .map(e => e._2)
.mapPartitions(partition => partition.map(e => e._2))

正如您从前面的注释中已经知道的那样,客户端无法将列表作为查询参数发送,并且服务器希望它在正文中。

使用上面的代码,客户端在正文中发送列表,服务器从 body 中读取列表。

从不发送列表作为查询参数,即使列表很小。 URL长度有一个限制,并且如果POST方法允许您使用请求正文发送信息,为什么还要在URL上公开参数...

答案 4 :(得分:-1)

是的,因为您尝试发送模型,它是null,但在另一种方法中,您尝试获取对象列表。 在您的请求将被读取之后,您必须获取涉及对象列表的对象。

ModContacts([FromBody] ContactDTO prod)

在ContactDTO中,您必须有一个可序列化的对象列表