c# - 当我点击谷歌对话流的端点但相同的谷歌对话流端点在邮递员中工作时,在 C# 中出现错误
问题描述
我在 PostMan 中使用这个端点:-
https://api.dialogflow.com/v1/query?v=20150910
我发送的这个 JSON 字符串:-
{"query":"flights from NYC to Vadodara","sessionId":"6b9d4676-2a71-4c64-a562-8c08f198c623","lang":"pt-BR","resetContexts":false}
我在邮递员中设置内容类型和授权。
所有这些东西都在邮递员中完美运行,但问题是当我使用 c# 代码到达这个端点时它不起作用它给我这个错误: -
我得到的错误:-
{
"id": "7b0ac743-58ea-4d61-a41d-a299f086a816",
"timestamp": "2018-06-04T15:30:25.873Z",
"lang": "en",
"status": {
"code": 400,
"errorType": "bad_request",
"errorDetails": "Invalid request content type, expecting \"multipart/form-data\" or \"application/json; charset\u003dutf-8."
}
}
这是我的代码:
using ApiAi.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication6
{
class Program
{
static void Main(string[] args)
{
HttpClient http = new HttpClient();
http.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));//ACCEPT header
http.DefaultRequestHeaders.Add("ContentType", "application/json; charset=utf-8");
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "xxx");
var response = http.PostAsync("https://api.dialogflow.com/v1/query?v=20150910", new StringContent(new Program().getSessionID(new ConfigModel { AccesTokenClient = "xxx" }, "flights from NYC to Vadodara"))).Result.Content.ReadAsStringAsync().Result;
}
public string getSessionID(ConfigModel config, string message)
{
var requestData = new RequestModel
{
query = message,
sessionId = (config.SessionId ?? Guid.NewGuid()).ToString(),
lang = "pt-BR"
};
return JsonConvert.SerializeObject(requestData);
}
}
public class RequestModel
{
public string query { get; set; }
public string sessionId { get; set; }
public string lang { get; set; }
public bool resetContexts { get; set; }
}
}
//
// Copyright (c) 2017 Nick Rimmer. All rights reserved.
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
//
using ApiAi.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ApiAi.Models
{
/// <summary>
/// Services configuration
/// </summary>
public class ConfigModel
{
#region magic
internal static string
BaseUrl = @"https://api.dialogflow.com/v1",
VersionCode = @"20150910";
#endregion
/// <summary>
/// Each API request requires authentication to identify the agent that is responsible for making the request. Authentication is provided through an access token.
/// The developer access token is used for managing entities and intents.
/// </summary>
public string AccesTokenDeveloper { get; set; }
/// <summary>
/// Each API request requires authentication to identify the agent that is responsible for making the request. Authentication is provided through an access token.
/// The client access token is used for making queries.
/// </summary>
public string AccesTokenClient { get; set; }
/// <summary>
/// Specifed language in your Api.ai agent
/// </summary>
public LanguagesEnum Language { get; set; }
/// <summary>
/// Timezone requests parameter
/// </summary>
public string TimeZone { get; set; } = System.TimeZone.CurrentTimeZone.StandardName;
/// <summary>
/// Session ID for request
/// </summary>
public object SessionId { get; set; } = Guid.NewGuid();
}
}
这是我正在使用的代码。提前致谢。
解决方案
StringContent本身有一个重载来设置内容类型:
var response = http.PostAsync(yourUrl,
new StringContent("your json string",
Encoding.UTF8, "application/json"))
.Result.Content.ReadAsStringAsync().Result;
默认媒体类型设置为:text/plain
Ps:您可能希望将这些拆分为更具可读性的功能。它在调试时很有帮助。
文档在这方面非常模糊,但正如您在此处看到的那样,StringContent
它有自己的Headers
属性。我的猜测是它将覆盖您的请求标头。
反编译程序集会显示媒体类型的默认值,如您所见text/plain
:
/// <summary>Creates a new instance of the <see cref="T:System.Net.Http.StringContent" /> class.</summary>
/// <param name="content">The content used to initialize the <see cref="T:System.Net.Http.StringContent" />.</param>
[__DynamicallyInvokable]
public StringContent(string content)
: this(content, (Encoding) null, (string) null)
{
}
/// <summary>Creates a new instance of the <see cref="T:System.Net.Http.StringContent" /> class.</summary>
/// <param name="content">The content used to initialize the <see cref="T:System.Net.Http.StringContent" />.</param>
/// <param name="encoding">The encoding to use for the content.</param>
/// <param name="mediaType">The media type to use for the content.</param>
[__DynamicallyInvokable]
public StringContent(string content, Encoding encoding, string mediaType)
: base(StringContent.GetContentByteArray(content, encoding))
{
this.Headers.ContentType = new MediaTypeHeaderValue(mediaType == null ? "text/plain" : mediaType)
{
CharSet = encoding == null ? HttpContent.DefaultStringEncoding.WebName : encoding.WebName
};
}
PS:你也可以试试:
//since utf-8 is the default.
http.DefaultRequestHeaders.Add("ContentType", "application/json");
推荐阅读
- javascript - Redux Form Wizard,按钮发送json字段数据?
- python - 如何使用 textblob 通过机器学习检测正确的电子邮件地址?
- bash - 如何按日期顺序grep文件
- python - Python - 根据表列中的逗号分隔值写入新行
- html - 删除最大字符宽度
- elixir - 使用来自另一个模块的 GenServer
- spring - 使用 Junit 进行 Spring Boot 测试
- file - C++/CLI:richTextBox 到带有换行符的 .txt
- python - Tensor Flow Lite Raspberry Pi 安装
- maven - 在 jenkins/blueocean docker 容器中安装 Maven