在ASP.NET Core MVC中无法调用具有类参数带有[FromBody]属性的类的API Post方法

时间:2018-09-13 18:20:01

标签: c# asp.net asp.net-mvc asp.net-core

我正在asp.net核心mvc中开发API以进行在线预订。但是,当我尝试从API post方法添加保留项时,出现错误:

  

WebException:远程服务器返回错误:(415)不支持   媒体类型。 System.Net.HttpWebRequest.GetResponse()

有2个项目:

项目1

我的API操作方法中有一个post方法,它具有[FromBody]属性。我必须调用此方法并传递保留对象。

方法定义为:

[HttpPost]
public Reservation Post([FromBody] Reservation res) =>
repository.AddReservation(new Reservation
{
    Name = res.Name,
    FromLocation = res.FromLocation,
    ToLocation = res.ToLocation
});

项目2 在项目2中,我想调用此API方法。为此,我在视图中创建了一个表单以填充名称(从位置到位置值)。然后,在控制器上,我必须调用API方法(如上所述)。

控制器代码为:

[HttpPost]
public IActionResult AddReservation(Reservation reservation)
{
    HttpWebRequest apiRequest = WebRequest.Create("http://localhost:8888/api/Reservation") as HttpWebRequest;
        apiRequest.Method = "Post";
        string parameters = "Name=" + reservation.Name + "Image=" + reservation.Image + "&FromLocation=" + reservation.FromLocation + "&ToLocation=" + reservation.ToLocation;
        byte[] byteArray = Encoding.UTF8.GetBytes(parameters);
        apiRequest.ContentType = "application/x-www-form-urlencoded";
        apiRequest.ContentLength = byteArray.Length;
        // Add the post data to the web request
        Stream postStream = apiRequest.GetRequestStream();
        postStream.Write(byteArray, 0, byteArray.Length);
        postStream.Close();

        string apiResponse = "";
        using (HttpWebResponse response = apiRequest.GetResponse() as HttpWebResponse)
        {
            StreamReader reader = new StreamReader(response.GetResponseStream());
            apiResponse = reader.ReadToEnd();
        }
        return RedirectToAction("Index");
}

我遇到错误-WebException:远程服务器返回错误:(415)不支持的媒体类型。 System.Net.HttpWebRequest.GetResponse()

但是当我运行powershell命令时,它会起作用:

PM> Invoke-RestMethod http://localhost:8888/api/Reservation -Method POST -Body (@{Name="Anne"; ToLocation="Meeting Room 4"} | ConvertTo-Json) -ContentType "application/json"

请帮助?

2 个答案:

答案 0 :(得分:3)

在前者中,您将请求正文编码为x-www-form-urlencoded,在后者中,您将编码为application/json。相同的动作不能同时响应两者。由于参数用[FromBody]装饰,因此application/json是您应该使用的参数,这就是powershell命令起作用的原因。

如果您实际上想要 x-www-form-urlencoded,请删除[FromBody]属性。如果您确实需要同时支持两者,则需要两条单独的路线:

private Reservation PostCore(Reservation res)
{
    // do something
}

[HttpPost("json")]
public Reservation PostJson([FromBody] Reservation res) => PostCore(res);

[HttpPost("")]
public Reservation PostForm(Reservation res) => PostCore(res);

答案 1 :(得分:1)

您的POST代码中有两个问题,首先是我在评论中提到过,克里斯在他的回答中提到过。

第二个是如何生成请求的正文,请使用类似以下的内容:

var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://url");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";

using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
    string json = "{\"user\":\"test\"," +
                  "\"password\":\"bla\"}";

    streamWriter.Write(json);
    streamWriter.Flush();
    streamWriter.Close();
}

var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
    var result = streamReader.ReadToEnd();
}

anwser

中的代码

您还可以使用Json.Net来序列化您的预订(如果所有字段名称和类型都匹配)