如何从Postman获取表单数据到WebApi

6

我想从Postman接收表单数据:

enter image description here

Content-Type: application/json

这是WebApi方法:

[HttpPost]
[Route("api/test")]
public async Task TestMethod(HttpRequestMessage request)
{
    var test = await request.Content.ReadAsStringAsync();
}

我明白您需要的是什么:

我的理解是:

------WebKitFormBoundarypqDvmeG89cBR9mK9
Content-Disposition: form-data; name="test"

esad
------WebKitFormBoundarypqDvmeG89cBR9mK9--

但是我不想要包含WebKitFormBoundary的数据,而且我有使用formdata的限制。还有其他方法吗?

HTTP调用信息:

POST /api/test HTTP/1.1
Host: localhost:16854
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Cache-Control: no-cache
Postman-Token: 1a3d6427-4956-707d-da0c-3a29a63c7563

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="test"

esad
------WebKitFormBoundary7MA4YWxkTrZu0gW--

curl调用信息:

curl -X POST \
  http://localhost:16854/api/test \
  -H 'cache-control: no-cache' \
  -H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \
  -H 'postman-token: 02055873-e9a8-e9a6-019c-b407992b0e2f' \
  -F test=esad 

这个 WebApi 方法放在你的代码哪里了?我在我的 MvcApplication 中启动它时遇到了问题... - foyss
3个回答

18

1)如果您必须发送Content-Type:multipart/form-data或者简单地发送form-data

这是Postman的第一个tab

输入图像描述

如果您只需要收集已发布的form-data中的一个键/值对,请执行以下操作。

[HttpPost]
[Route("api/test")]
public HttpResponseMessage TestMethod(HttpRequestMessage request)
{
    var testValue = HttpContext.Current.Request.Form["test"];

    return Request.CreateResponse(HttpStatusCode.OK, testValue);
}

如果您需要收集您发布的form-data的多个键/值对

[HttpPost]
[Route("api/test")]
public HttpResponseMessage TestMethod(HttpRequestMessage request)
{
    NameValueCollection collection = HttpContext.Current.Request.Form;

    var items = collection.AllKeys.SelectMany(collection.GetValues, (k, v) => new { key = k, value = v });

    //We just collect your multiple form data key/value pair in this dictinary
    //The following code will be replaced by yours
    Dictionary<string, string> keyValuePairs = new Dictionary<string, string>();

    foreach (var item in items)
    {
        keyValuePairs.Add(item.key, item.value);
    }

    return Request.CreateResponse(HttpStatusCode.OK, keyValuePairs);
}

2) 如果你需要发送 Content-Type: application/x-www-form-urlencoded

这是Postman的第二个标签页

在此输入图片描述

那么你的API将会是:

[HttpPost]
[Route("api/test")]
public async Task TestMethod(HttpRequestMessage request)
{
    var test = await request.Content.ReadAsFormDataAsync();
}

如果您在代码中设置了断点并进行调试,将会得到以下输出:

显示图像描述


3) 如果您必须发送Content-Type: application/json

这是Postman的第三个标签页

请参考下面的截图:

显示图像描述

接口如下:

[HttpPost]
[Route("api/test")]
public async Task TestMethod(HttpRequestMessage request)
{
     var jObject = await request.Content.ReadAsAsync<JObject>();

     Item item = JsonConvert.DeserializeObject<Item>(jObject.ToString());
}

以及您的模型来收集这些发布的数据

public class Item
{
    public string test { get; set; }
}

你的输出将会是:

在此输入图片描述

这个选项的优点是你可以发送 complex type 作为发布的数据,例如:

在此输入图片描述

而你的API则是:

[HttpPost]
[Route("test")]
public async Task TestMethod(HttpRequestMessage request)
{
    var jObject = await request.Content.ReadAsAsync<JObject>();

    Sample sample = JsonConvert.DeserializeObject<Sample>(jObject.ToString());
}

而你所用来收集这些数据的模型为:

public class Item
{
    public string test { get; set; }
}

public class Sample
{
    public Item item { get; set; }
}

然后你会看到输出是

在这里输入图片描述


你是否有使用async/await的需求? - er-sho
不,无论如何我都想获取 form-data - Hina Khuman
我们怎样获取headers数据? - Moeez
1
@Faisal,尝试使用HttpContext.Current.Request.Headers,并使用linq获取您的键值对。 - er-sho
@Faisal,在我为您添加新代码之前,您可以尝试使用以下代码=> var jArray = await request.Content.ReadAsAsync<JArray>(); List<Sample> lstSamples = JsonConvert.DeserializeObject<List<Sample>>(jArray.ToString()) 其中Sample是包含您的msn和global_device_id属性的类。 - er-sho
显示剩余3条评论

1
以下代码将在使用 Postman 并选择 form-data 选项时正确读取键值对。
[HttpPost]
[Route("api/test")]
public async Task<HttpResponseMessage> TestMethod(HttpRequestMessage request)
{
    string root = HttpContext.Current.Server.MapPath("~/App_Data");
    var provider = new MultipartFormDataStreamProvider(root);

    await Request.Content.ReadAsMultipartAsync(provider);

    var testValue = provider.FormData.GetValues("test")[0];

    return Request.CreateResponse(HttpStatusCode.OK);
}

更详细的示例可以在这里找到(章节:读取表单控件数据)。

编辑:发送到上述API处理程序的HTTP调用如下:

POST /api/stats/testmethod HTTP/1.1
Host: localhost:4100
Cache-Control: no-cache
Postman-Token: 999fd13d-f804-4a63-b4df-989b660bcbc5
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="test"

esad
------WebKitFormBoundary7MA4YWxkTrZu0gW--

感谢您的回答!但是在等待时出现了错误:“ExceptionMessage”:“提供的'HttpContent'实例无效。它没有以'multipart/'开头的内容类型标头。\r\n参数名称:内容”, - Hina Khuman
@HinaKhuman,你能分享一下你在Postman中尝试的API调用的curl命令吗? - Tasos K.
不确定curl命令,我正在使用Content-Type: application/json - Hina Khuman
谢谢您告诉我,已添加到问题中。 - Hina Khuman
1
好的,没问题,我明天早上会检查一下,我想我需要一些新鲜空气 :) 谢谢你的努力,Tasos,我非常感激。 - Hina Khuman
显示剩余3条评论

0

以下语句可以实现此功能:

NameValueCollection form = HttpContext.Current.Request.Form;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接