asp.net 对Web API的简单POST请求根本不会命中API

hpcdzsge  于 2022-11-19  发布在  .NET
关注(0)|答案(4)|浏览(159)

在我的MVC应用程序中,我尝试向名为MembershipController的API控制器中的这些示例端点(操作)发出POST请求:

[HttpPost]
public string GetFoo([FromBody]string foo)
{
    return string.Concat("This is foo: ", foo);
}

[HttpPost]
public string GetBar([FromBody]int bar)
{
    return string.Concat("This is bar: ", bar.ToString());
}

[HttpPost]
public IUser CreateNew([FromBody]NewUserAccountInfo newUserAccountInfo)
{
    return new User();
}

下面是客户端代码:

var num = new WebAPIClient().PostAsXmlAsync<int, string>("api/membership/GetBar", 4).Result;

下面是WebAPIClient类的代码:

public class WebAPIClient
{
    private string _baseUri = null;

    public WebAPIClient()
    {
        // TO DO: Make this configurable
        _baseUri = "http://localhost:54488/";
    }

    public async Task<R> PostAsXmlAsync<T, R>(string uri, T value)
    {
        using (var client = new HttpClient())
        {
            client.BaseAddress = new Uri(_baseUri);

            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));

            var requestUri = new Uri(client.BaseAddress, uri);

            var response = await client.PostAsXmlAsync<T>(requestUri, value);

            response.EnsureSuccessStatusCode();

            var taskOfR = await response.Content.ReadAsAsync<R>();

            return taskOfR;
        }
    }
}

我为Web API定义了以下默认路由:

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

UPDATE我的程式码会中断调试工具,直到System.Net.HttpClient程式码上的PostAsXmlAsync方法被呼叫为止。然而,Fiddler中没有显示任何要求。

然而,如果我试图在Fiddler中编写POST请求,或者试图通过浏览器向某个API端点发出GET请求,通过Fiddler编写的POST请求告诉我我没有发送任何数据,我必须发送。浏览器发送的GET请求正确地告诉我该操作不支持GET请求。
看起来System.Net.HttpClient类没有正确发送POST请求。

ggazkfy8

ggazkfy81#

最常见的问题之一是您没有使用适当的属性。
考虑到ASP.NETMVC和ASP.NETWebAPI的属性具有相同的名称,但它们位于不同的命名空间中:

这是一个非常非常常见的错误,它会影响MVC和Web API中存在的所有东西。因此,当使用可能存在于两个世界中的东西时,必须非常小心(例如过滤器、属性或依赖注入注册)。

n53p2ov0

n53p2ov02#

我也遇到过类似的问题(可能不是同一个问题)。在我的例子中,我没有给input元素赋予name属性。我只是在fiddler显示没有post数据发送到服务器时才意识到这一点(就像你的例子一样)。

<input id="test" name="xyz" type="text" />

在input标记中添加name属性解决了我的问题。
但是,还有一点需要注意。WebAPI不会直接将表单数据放入参数中。您必须创建一个具有这些属性的对象,然后将该对象放入post控制器的参数中。或者您可以完全不放置参数,如下所示:

[Route("name/add")]

    public async Task Post()
    {
        if (!Request.Content.IsMimeMultipartContent())
        {
            return;
        }

        var provider = PostHelper.GetMultipartProvider();
        var result = await Request.Content.ReadAsMultipartAsync(provider);
        var clientId = result.FormData["xyz"];
        ...
hyrbngr7

hyrbngr73#

请尝试将FromBody更改为FromUri。
如果参数是“简单”类型,Web API会尝试从URI取得值。简单类型包括.NET基本类型(int、bool、double等),加上TimeSpan、DateTime、Guid、decimal和string,以及任何具有可从字串转换的类型转换子的类型。
对于复杂类型,Web API尝试使用媒体类型格式化程序从消息正文中读取值。

ryoqjall

ryoqjall4#

完全删除FromBody,并且在传递参数时不做任何限制(此时它可以在uri、查询字符串或表单提交中传递(这有点类似于查询字符串))

[HttpPost]
public string GetFoo(string foo){...}

它将被隐式分析和传递。

相关问题