简体   繁体   English

使用HttpClient发布到Web API 2操作时出现404错误

[英]404 error when posting to Web API 2 action using HttpClient

OK, there is lots going on here so I will try and keep my question and examples as simple as I can. 好的,这里发生了很多事情,因此我将尝试使我的问题和示例尽可能简单。 With that in mind, please ask if you need any additional information or clarification on anything. 考虑到这一点,请询问您是否需要任何其他信息或任何说明。

The code 编码

I have a Web API 2 project which has a number of controllers and actions. 我有一个Web API 2项目,其中包含许多控制器和操作。 The particular action I am having problems with is defined in the ContactController as follows: 我遇到问题的特定操作在ContactController中定义如下:

[HttpPost]
public MyModel GetSomething(System.Nullable<System.Guid> uid)
{
    return GetMyModel(uid);
}

In case it matters, my routing is setup as follows: 万一重要,我的路由设置如下:

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = RouteParameter.Optional }
);

Now I have another project that is required to call the above action. 现在,我有另一个项目需要调用上述操作。 For calling the Web API I am using HttpClient . 为了调用Web API,我使用HttpClient Note that I have lots of other actions calls which are working correctly, so this isn't a connectivity issue. 请注意,我还有许多其他的操作调用都可以正常运行,因此这不是连接问题。

The code I am using to call the Web API method is as follows: 我用来调用Web API方法的代码如下:

using (HttpClient client = GetClient())
{
    var obj = new List<KeyValuePair<string, string>> { new KeyValuePair<string, string>("uid", someGuid.ToString()) };
    var response = client.PostAsync(path, new FormUrlEncodedContent(obj)).Result;

    return response.Content.ReadAsAsync<T>().Result;
}

In this instance, path is basically: 在这种情况下, path基本上是:

localhost:12345/api/contact/getsomething 本地主机:12345 / api / contact / getsomething

The problem 问题

The PostAsync call Result (ie response in the above code) gives this message: PostAsync调用Result (即上述代码中的response )给出以下消息:

{StatusCode: 404, ReasonPhrase: 'Not Found', Version: 1.1, Content: System.Net.Http.StreamContent, Headers: { Pragma: no-cache X-SourceFiles: =?UTF-8?B?QzpcRGV2ZWxvcG1lbnRcUHJvamVjdHNcTGltYVxMaW1hIHYzXERFVlxMaW1hRGF0YVNlcnZpY2VcYXBpXHVzZXJhY2Nlc3NcZ2V0bW9kdWxlc2FjY2Vzcw==?= Cache-Control: no-cache Date: Fri, 18 May 2018 10:25:49 GMT Server: Microsoft-IIS/10.0 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Content-Length: 222 Content-Type: application/json; {的StatusCode:404,ReasonPhrase: '未找到',版本:1.1,内容:System.Net.Http.StreamContent,集管:{杂注:无缓存X-SourceFiles:???= UTF-8乙QzpcRGV2ZWxvcG1lbnRcUHJvamVjdHNcTGltYVxMaW1hIHYzXERFVlxMaW1hRGF0YVNlcnZpY2VcYXBpXHVzZXJhY2Nlc3NcZ2V0bW9kdWxlc2FjY2Vzcw ==? =缓存控制:无缓存日期:2018年5月18日星期五10:25:49 GMT服务器:Microsoft-IIS / 10.0 X-AspNet版本:4.0.30319 X-Powered-由:ASP.NET内容长度: 222内容类型:application / json; charset=utf-8 Expires: -1 }} charset = utf-8过期:-1}}

If I put a breakpoint inside the aciton then it doesn't fire. 如果我将一个断点放在aciton中,那么它不会触发。 However, what I find strange is that when I call it, Visual Studio (2018) tells me that the specific action has a "failed request" on that specific action. 但是,令我感到奇怪的是,当我调用它时,Visual Studio(2018)告诉我特定操作对该特定操作有一个``失败请求''。 So clearly it must know which method I am trying to call? 因此,很明显它必须知道我要尝试调用的方法?

At this point I am running out of ideas on how to debug further. 在这一点上,我没有关于如何进一步调试的想法。 What am I doing wrong here? 我在这里做错了什么?

in this case you can use the same endpoint as for getting and posting. 在这种情况下,您可以使用与获取和发布相同的端点。

so you probably need: 因此,您可能需要:

[HttpGet]
public IActionResult Get(System.Nullable<System.Guid> uid)
{
    return GetMyModel(uid); //make sure you got it, oterhwise return a NotFound()
}

[HttpPost]
public IActionResult Post(InputModel model)
{
    _service.doMagicStuff();
    return Ok();
}

cheers! 干杯!

not sure but error may be because of you are passing keyvalue pair 不确定但错误可能是由于您传递键值对

var obj = new List<KeyValuePair<string, string>> { new KeyValuePair<string, string>("uid", someGuid.ToString()) };
var response = client.PostAsync(path, new FormUrlEncodedContent(obj)).Result;

instead of guild only ie only string value expected by function , so it will be 而不是公会,即仅函数期望的字符串值,因此它将是

var response = client.PostAsync(path, new FormUrlEncodedContent(someGuid.ToString())).Result;

method should be 方法应该是

[HttpPost]
public MyModel GetSomething(string uid)
{
    return GetMyModel(Guid.Parse( uid));
}

You are sending the guid with the FormUrlEncodedContent but the requests content type is application/json. 您正在发送带有FormUrlEncodedContent的GUID,但请求的内容类型为application / json。 I recommend you to send it as a json like this 我建议您像这样将其作为json发送

using (HttpClient client = GetClient())
{
    var obj = new { uid = someGuid.ToString()) };
    var json = JsonConvert.SerializeObject(obj);
    var content = new StringContent(json, Encoding.UTF8, "application/json");
    var result = client.PostAsync(path, content).Result;

    return response.Content.ReadAsAsync<T>().Result;
}

Then in the api controller, use the FromBody attribute to declare that the parameter is read from the request body 然后在api控制器中,使用FromBody属性声明从请求正文中读取参数

[HttpPost]
public MyModel GetSomething([FromBody]RequestModel model)
{
    return GetMyModel(model.uid);
}

public class RequestModel
{
    public System.Nullable<System.Guid> uid { get; set; }
}

Also, if you only have one Post method in the contact controller the url localhost:12345/api/contact will be enough 另外,如果联系人控制器中只有一个Post方法,则URL localhost:12345/api/contact就足够了

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM