【问题标题】:Using C# Restsharp, how can I replicate a form post?使用 C# Restsharp,如何复制表单帖子?
【发布时间】:2016-05-18 21:58:02
【问题描述】:

我正在使用休息服务来取回一些 json 数据。作为测试工具,他们给了我一个 url,如果我在浏览器中访问该 url,我有一个表单,我可以将一些 json 放在 textarea 中,然后提交表单,我在页面重新加载时得到 json 结果.

我现在尝试通过在 C# 中使用 RestSharp 以编程方式复制此内容,但我遇到了一个问题,即调用的结果是我要访问的页面的 html(而不是 json 结果)

这是我的代码:

var client = new RestClient {BaseUrl = new Uri("http://myhost.com:22333") };        

var request = new RestRequest { Method = Method.POST, Resource = "/site/api", RequestFormat = DataFormat.Json };

 request.AddBody(new
        {
            fieldtype = "name", value = "joe"
        });
        request.AddHeader("accept", "application/json");

        client.Authenticator = new NtlmAuthenticator();
        var response = client.Execute(request);
        var jsonDto = new JsonDeserializer().Deserialize<ResultObj>(response);

如果我在调试器中查看 response.Content(在任何反序列化之前),我会看到我使用表单发布的网页的 html 字符串(类似这样)

<html>
<body>
<form method='POST'>
<table>
<tr>
<td>Enter the JSON:</td>
<td>
<textarea name="json_input" cols="80" rows="30">
</textarea>
</td>
</tr>
<tr><td colspan='2'><input type='Submit' value='submit'></td></tr>
</table>
</form>
</body>
</html>

有人可以告诉我这里缺少什么,因为我希望在响应中得到相同的 json 结果。我在浏览器中提交表单后看到的内容

【问题讨论】:

  • 当您在测试工具中发布带有数据的form 时,url 是什么?
  • 如果您可以分享 url 和示例 json,我们将能够提供帮助。
  • 请确保 API 方法是 POST(不是 GET 或其他)
  • 请检查 /api 之外不需要额外的路径。例如。网站/api/客户
  • @Guruprasad Rao - myhost.com:22333/site/Api

标签: javascript c# jquery json restsharp


【解决方案1】:

HTML 代码所示,表单的操作 URL 将等待以下表单字段:

  • json_input

在您的代码中,您正在调用 request.AddBody(new { ... }),它执行以下操作:

  • 当您将RequestFormat 设置为DataFormat.Json 时,默认使用的序列化程序是JsonSerializer
  • Content-Type 标头设置为“application/json”。
  • new { ... } 将被序列化为 json 字符串,AddBody() 调用转换为对 AddParameter() 的调用,使用作为参数 name “application/json”,作为参数 value json 字符串,并作为参数 type ParameterType.RequestBody.

使用 Fiddler2 您可以看到您的代码生成的 POST

如图所示,请求正文是{"fieldtype":"name", "value":"joe"},如果服务器期望表单字段fieldtypevalue,这可能有效;但期待这样的请求正文json_input={ "fieldtype": "name", "value": "joe" }(为清楚起见已解码)。在下一张图片中,您可以看到使用 HTMLPOST

另外,添加参数的类型是ParameterType.RequestBody,所以只使用AddBody()函数添加的第一个body,其余的都被丢弃。

您可以通过创建一个名为“json_input”的Parameter 并将其传递给函数AddParameter() 来解决此问题:

var client = new RestClient { BaseUrl = new Uri("http://myhost.com:22333") };

var request = new RestRequest { Resource = "/site/api", RequestFormat = DataFormat.Json };

var param = new Parameter
{
    Type = ParameterType.GetOrPost,
    Name = "json_input",
    Value = new
    {
        fieldtype = "name",
        value = "joe"
    }
};

request.AddParameter(param);

client.Authenticator = new NtlmAuthenticator();

var response = client.Post(request);            

if (response.StatusCode == System.Net.HttpStatusCode.Created)
{
    var deserializer = new JsonDeserializer();
    var jsonDto = deserializer.Deserialize<ResultObj>(response);
}

使用ParameterType.GetOrPost 允许您添加任意数量的参数(表单字段)。

正如您在我的代码中看到的,我添加了一个 if 语句检查响应中返回的 HTTP StatusCode,因为通常 HTTP POST 返回一个 201 已创建代码。

您可以添加else 语句来检查属性response.ErrorExceptionresponse.ErrorMessage 以查看问题所在。

也许,由于 POST 格式不正确,服务器会将您重定向到同一页面再试一次。

【讨论】:

    【解决方案2】:

    确保根据 API 控制器方法的预期创建模型。 我使用您提供的信息创建了一个示例,您需要将所有表单字段添加到模型中。

    //Model for the data you are sending
    public class TestModel
    {
        public string Name { get; set; }
    }
    
    //define client, request and model
    var client = new RestClient {BaseUrl = new Uri("http://myhost.com:22333") };        
    var request = new RestRequest { Method = Method.POST, Resource = "/site/api", RequestFormat = DataFormat.Json };
    var testModel = new TestModel() { Name = "joe" };
    
    //serialize model as json and add it to the request
    var json = request.JsonSerializer.Serialize(testModel);
    request.AddParameter("application/json; charset=utf-8", json, ParameterType.RequestBody);
    
    //execute request
    IRestResponse response = client.Execute(request);
    

    确保您发布到 API 的正确 URI。

    继续检查您收到的 HTML,看看它是否给您任何错误。

    希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      form 有一个名为 json_input 的文本字段,将用作请求参数。

      <textarea name="json_input" cols="80" rows="30">
      

      您的AddBody 方法表明您正在发送带有fieldtypevalue 参数的请求。

      尝试将AddBody 方法替换为以下内容:

      request.AddBody(new { json_input = "{ fieldtype : \"name\", value : \"joe\"}" });
      
      //OR
      
      request.AddParameter("json_input",
                          "{ fieldtype : \"name\", value : \"joe\"}");
      

      【讨论】:

        【解决方案4】:

        试试这个:

        var client = new RestClient {"http://myhost.com:22333/site/api"};        
        
        var request = new RestRequest {  RequestFormat = DataFormat.Json };
        
         request.AddBody(new
                {
                    fieldtype = "name", value = "joe"
                });
        
                client.Authenticator = new NtlmAuthenticator();
                var response = client.Post(request);
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    var jsonDto = new JsonDeserializer().Deserialize<ResultObj>(response);
        

        【讨论】:

        • 这似乎与我在问题中的当前代码做同样的事情
        猜你喜欢
        • 2016-04-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-09
        • 2020-01-10
        • 1970-01-01
        • 2012-05-10
        • 1970-01-01
        相关资源
        最近更新 更多