Web API POST失败,使用RestSharp

时间:2015-11-20 14:36:08

标签: c# post asp.net-web-api restsharp

在我看来,尝试使用RestSharp客户端使用WebApi POST方法时发生了一些奇怪的事情。以下代码分别适用于服务器(WebApi)和客户端。

服务器WebApi

[Route("UserRoles")]
[AllowAnonymous]
public IHttpActionResult Post(
    [FromBody] UserroleDto userroleDto,
    [FromUri] string appCode)
{
  return OK();
}

测试客户端

[TestInitialize()]
public void Initialize()
{
    _restClient = new RestClient("http://localhost:8089");
}

[TestMethod]
public void Can_Store_A_Userrole_Via_REST_WebAPI()
{
    var request = new RestRequest(ApiBasePath, Method.POST);

    request.AddUrlSegment("segment", "UserRoles");
    request.RequestFormat = DataFormat.Json;
    request.AddBody(
        new UserroleDto()
        {
            UserRoleId = -1,
            Role = "Developer"
        });

    request.AddHeader("appCode", AppCode);
    //request.AddParameter("appCode", AppCode);

    _restClient.Execute(request);
}

方案是:

  1. 如果我注释掉POST方法中的[FromUri] string appCode和测试中的request.AddParameter("appCode", AppCode);,那么测试通过。
  2. 如果我在POST方法中包含[FromUri] string appCode并且我从POSTMAN运行该方法,则测试通过。
  3. 如果我分别在POST方法中包含[FromUri] string appCode而在测试中包含request.AddParameter("appCode", AppCode);,则测试失败。错误信息: 控制器上找不到方法
  4. 欢迎任何建议!

2 个答案:

答案 0 :(得分:1)

首先,我将解释您的方案中经验丰富的行为。然后我会提供一个解决方案。

  1. 如果我从POST方法中注释掉[FromUri]字符串appCode 和request.AddParameter(“appCode”,AppCode);从测试中, 测试通行证。
  2. 在这种情况下,服务器不希望任何地方appCode,测试也不会发送它。测试似乎通过,但我是误报。服务器根本没有收到appCode

    1. 如果我在POST上包含[FromUri]字符串appCode 方法和我从POSTMAN运行方法,测试通过。
    2. 我猜你在POSTMAN中使用这个URL:

      http://localhost:8089/UserRoles?appCode=SomeAppCode
      

      在这种情况下,ASP.NET Web API从URL中提取appCode,从主体中提取DTO。然后,服务器方法按预期执行。

      1. 如果我在POST方法中包含[FromUri]字符串appCode和 request.AddParameter(“appCode”,AppCode);分别在测试中, 测试失败。错误消息:控制器上找不到方法
      2. 失败的原因是appCode被添加到正文中。然而,服务器希望它在uri中。因此,框架无法找到与uri匹配的方法并抛出上述错误。

        <强>解决方案

        如果可以,我会改变路线和行动:

        [Route("UserRoles/{appCode}"]
        [AllowAnonymous]
        public IHttpActionResult Post(string appCode, UserroleDto userroleDto)
        {
            return OK();
        }
        

        通过此更改,网址变为:

        http://localhost:8089/UserRoles/SomeAppCode
        

        身体可以放入体内。

        您的测试代码将是:

        [TestMethod]
        public void Can_Store_A_Userrole_Via_REST_WebAPI()
        {
            var request = new RestRequest(ApiBasePath, Method.POST);
        
            request.AddUrlSegment("segment", "UserRoles");
            request.AddUrlSegment("segment", AppCode);
            request.RequestFormat = DataFormat.Json;
            request.AddBody(
                new UserroleDto()
                {
                    UserRoleId = -1,
                    Role = "Developer"
                });
        
            _restClient.Execute(request);
        }
        

答案 1 :(得分:0)

您尝试的行为的说明

  
      
  1. 如果我推荐出POST方法的[FromUri]字符串appCode和request.AddParameter(&#34; appCode&#34;,AppCode);来自   测试,测试通过。
  2.   

如果没有[FromUri],您的控制器希望通过请求体接收AppCode,这就是RestSharp.AddParameter()实际执行的操作。测试通过,一切都好!

  
      
  1. 如果我在POST方法中包含[FromUri]字符串appCode,并且我从POSTMAN运行该方法,则测试通过。
  2.   

在这里,您可能使用POSTMAN调用相应的URL,其中包含查询参数。测试通过,如果您查询的网址具有您期望的签名,那么一切都很好。

  
      
  1. 如果我在POST方法和request.AddParameter(&#34; appCode&#34;,AppCode)中包含[FromUri]字符串appCode;在测试上   分别,测试失败。错误消息:找不到方法   控制器
  2.   

这里,它失败了,因为控制器希望将AppCode作为查询参数接收。 (就像你可能用POSTMAN做的那样)。但是通过使用RestSharp.AddParameter(),您可能不会在正确的URL上发送查询,从而导致错误。

如何解决问题:定义api路径

您必须定义的是我的路线应该是什么样的

提出异议,可以说我该如何查询我的api?

选项1:使用查询参数

[FromUri]将定义您的控制器,以便它回答如下请求:

本地主机:8099 / appcode的UserRole = SOMETHING

如果这是您希望api拥有的网址,可能会相应地使用RestSharp:

var myAppCode="FOO"; var url = "localhost:8099/UserRoles?appCode={appCodeToQuery}"; request.addUrlSegment("appCodeToQuery",myAppCode);

选项2:使用POST正文

您可能更喜欢另一种风格,例如:

本地主机:8099 /的UserRole

因此,您可以使用POST的请求主体传递一些数据,例如:

var myAppCode="FOO"; request.addParameter("appCode",myAppCode);

应该通过请求BODY POST数据。

选项3:使用请求标头

另外,我怀疑你是否想要在Header中传递appCode。 如果你打电话,那就是RestSharp会做的事情:

request.AddHeader("appCode", AppCode);

其他选择?

是的,还有其他选项可用于向您的API发送数据。您将使用RestSharp测试的内容需要适合您的控制器实际实现的内容。