代码之家  ›  专栏  ›  技术社区  ›  leora Matt Lacey

使用C#Restsharp,我如何复制表单帖子?

  •  2
  • leora Matt Lacey  · 技术社区  · 9 年前

    我正在使用rest服务来获取一些json数据。作为一个测试工具,他们给了我一个url,如果我在浏览器中找到这个url,我有一个表单,我可以在文本区域中放置一些json,然后提交表单,我会在页面重新加载时得到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);
    

    如果我看看回应。在调试器中的内容(在任何反序列化之前),我看到了一个网页的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结果作为回应。在浏览器中提交表单后看到的内容

    4 回复  |  直到 9 年前
        1
  •  3
  •   Chris Wijaya    9 年前

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

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

    而你的 AddBody 方法表示您正在使用发送请求 fieldtype value 参数。

    尝试更换 添加正文 方法如下:

    request.AddBody(new { json_input = "{ fieldtype : \"name\", value : \"joe\"}" });
    
    //OR
    
    request.AddParameter("json_input",
                        "{ fieldtype : \"name\", value : \"joe\"}");
    
        2
  •  1
  •   mojorisinify    8 年前

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

    • json输入

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

    • 当您设置 RequestFormat DataFormat.Json ,默认情况下要使用的序列化程序为 JsonSerializer .
    • 内容类型 标题设置为“application/json”。
    • new { ... } 将序列化为json字符串 AddBody() 调用转换为对 AddParameter() 用作参数 名称 “application/json”,作为参数 价值 json字符串,作为参数 类型 ParameterType.RequestBody .

    使用 小提琴2 你可以看到 岗位 由您的代码生成:

    code fiddler

    如图所示,请求主体是 {"fieldtype":"name", "value":"joe"} ,如果服务器需要表单字段,这可能有效 字段类型 价值 ; 但需要这样的请求体 json_input={ "fieldtype": "name", "value": "joe" } (为清晰起见,已解码)。在下一张图中,您可以看到 岗位 使用 HTML语言 :

    html fiddler

    此外,添加的参数的类型为 参数类型.RequestBody ,因此仅使用添加的第一个正文 添加正文() 函数,其余的被丢弃。

    您可以通过创建 Parameter 调用“jsoninput”并将其传递给函数 添加参数() :

    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 语句检查 超文本传输协议 StatusCode 在响应中返回,因为通常 HTTP帖子 返回一个 201已创建 密码

    您可以添加 else 语句检查属性 response.ErrorException response.ErrorMessage 看看问题出在哪里。

    也许,作为 岗位 格式不正确,服务器会将您重定向到同一页面,然后重试。

        3
  •  0
  •   Sir Crusher    8 年前

    确保根据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,看看它是否会给您带来任何错误。

    希望这有帮助。

        4
  •  -1
  •   JohnWrensby    9 年前

    试试这个:

    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);