【问题标题】:WebApi POST method not found but GET works未找到 WebApi POST 方法,但 GET 有效
【发布时间】:2016-07-29 07:51:12
【问题描述】:

我今天尝试了很多次使用 POST (HttpClient.PostAsync) 方法调用 web api 函数。但不幸的是我做不到。 只有使用 GET (HttpClient.GetAsync) 方法的调用才能成功。 我尝试在网上跟踪许多示例,但总是出现相同的错误。 (“未找到”)

如果有人可以帮助我,非常感谢你

这里是 C# Web API:

[RoutePrefix("NewAreaMap")]
public class NewAreaMapController: ApiController
{
    [HttpPost]
    [ActionName("PostCreateAreaTemp")]
    public AreaTemp PostCreateAreaTemp(double southLatitude, double westLongitude, double northLatitude, double eastLongitude, int countryId, int worldId)
    {
        AreaTemp newTempMap = new AreaTemp();
        //.....
        * * Here is the C# code from client side: * *
            using(var client = new HttpClient())
            {
                client.BaseAddress = new Uri(ConfigurationManager.AppSettings["SrvWebApiPath"].ToString());
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                var values = new Dictionary < string,
                    string > ()
                    {
                        {
                            "southLatitude", southLatitude.ToString()
                        },
                        {
                            "westLongitude", westLongitude.ToString()
                        },
                        {
                            "northLatitude", northLatitude.ToString()
                        },
                        {
                            "eastLongitude", eastLongitude.ToString()
                        },
                        {
                            "countryId", countryId.ToString()
                        },
                        {
                            "worldId", worldId.ToString()
                        }
                    };
                var content = new FormUrlEncodedContent(values);
                HttpResponseMessage response = await client.PostAsync("api/NewAreaMap/PostCreateAreaTemp", content)
                if (response.IsSuccessStatusCode)
                {
                    string jsonData = response.Content.ReadAsStringAsync().Result;
                    newAreTemp = JsonConvert.DeserializeObject < AreaTemp > (jsonData);
                }
        }

GET 调用适用于以下 Url:

HttpResponseMessage response = await client.GetAsync("api/NewAreaMap/GetAreaTemp/?latitudeAreaCenter=7.02&longitudeAreaCenter=9.05");

【问题讨论】:

  • 网络服务器日志是否显示了除 404 之外更有趣的内容?
  • 您要 POST 到什么 URI?还请包含 GET URI。
  • 我在描述中添加

标签: c# rest asp.net-web-api2 webapp2


【解决方案1】:

由于您要发布 JSON,您不妨将其作为对象发送。或者,如果您仍想保留该方法的字典和签名,您可以尝试:

var content = new StringContent(JsonConvert.SerializeObject(values),
            Encoding.UTF8, "application/json");

代替

var content = new FormUrlEncodedContent(values);

这是一个带有对象的示例。

public class SampleObject
{
    public double SouthLatitude { get;  set; }
    public double WestLongitude { get; set; }
    public double NorthLatitude { get; set; }
    public double EastLongitude { get; set; }
    public int CountryId { get; set; }
    public int WorldId { get; set; }
}

并更改您的请求。

using (var client = new HttpClient())
{
    client.BaseAddress = new Uri(ConfigurationManager.AppSettings["SrvWebApiPath"].ToString());
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    var obj = new SampleObject
    {
        SouthLatitude = southLatitude,
        WestLongitude = westLongitude,
        NorthLatitude = northLatitude,
        EastLongitude = eastLongitude,
        CountryId = countryId,
        WorldId = worldId
    };

    // Send it as StringContent.
    var request = new StringContent(JsonConvert.SerializeObject(obj),
        Encoding.UTF8, "application/json");

    HttpResponseMessage response = await client.PostAsync("api/NewAreaMap/PostCreateAreaTemp", request)
    if (response.IsSuccessStatusCode)
    {
        string jsonData = response.Content.ReadAsStringAsync().Result;
        newAreTemp = JsonConvert.DeserializeObject<AreaTemp>(jsonData);
    }
}

还有服务器上的签名。

public AreaTemp PostCreateAreaTemp(SampleObject sampleObject)

或者如果需要:

public AreaTemp PostCreateAreaTemp([FromBody]SampleObject sampleObject)

【讨论】:

  • 谢谢,现在一切顺利。非常感谢,您花了很多时间为我写了一个完整的漂亮答案作为示例代码。
  • 出于好奇;你需要使用[FromBody]吗?我从不知道何时需要或不需要...
  • @smoksnes 是的,这里也是如此,因为它无需使用它也能工作。我看到像我这样的人时间开发人员使用它或有时不使用它,似乎它只是属性从微软提供的更安全的一面。
  • 不,我不需要:-)。它在没有 [FromBody] 的情况下运行良好
【解决方案2】:

用对象替换你的方法参数,因为你传递的是完整的对象 来自 httpclient 的“内容”,所以在这种情况下,您需要在这里使用相同的对象,也可以使用 [frombody] 属性 methodname([FromBody] 内容内容) 在一个类中定义所有属性并使用 .希望对你有所帮助。

【讨论】:

  • 谢谢,我给你一分,就像@smoksnes 说的那样。是答案的一部分
  • @MehdiBugnard 谢谢,我之前发布过,但我尊重 smoksnes 的回答,他用代码发布了答案。
【解决方案3】:

请尝试将 FromBody 属性与您的操作参数一起使用。

【讨论】:

  • 我们可以使用没有参数的frombody属性吗?
猜你喜欢
  • 1970-01-01
  • 2017-03-19
  • 2020-03-16
  • 2020-05-22
  • 2017-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多