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

时间:2016-02-09 03:01:44

标签: javascript c# jquery json restsharp

我正在使用休息服务来获取一些json数据。作为一个测试工具,他们给了我一个网址,如果我去浏览器的网址,我有一个表格,我可以把一些json放在textarea然后提交表单,我得到json结果回到页面重新加载。

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

这是我的代码:

RewriteCond %{THE_REQUEST} ^GET\ /([^?]+)\?subpage=([^&\s]+) [NC]
RewriteRule ^.+$ /%1/%2? [R=301,L]

RewriteRule ^(.+)/([^/]+)/?$ /$1.php?subpage=$2 [L]

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

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

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

4 个答案:

答案 0 :(得分: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\"}");

答案 1 :(得分:1)

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

  • json_input

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

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

使用 Fiddler2 ,您可以看到代码所做的 POST

code fiddler

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

html fiddler

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

您可以通过创建名为&#34; json_input&#34;的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 Created 代码。

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

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

答案 2 :(得分:0)

确保根据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 :(得分:-1)

试试这个:

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