为了账号安全,请及时绑定邮箱和手机立即绑定

通过WebApi返回JSON

通过WebApi返回JSON

C#
九州编程 2023-12-17 17:00:27
我正在使用 C# 中的 HttpClient 尝试将 SSO(单点登录)集成到我们的一些自定义应用程序中。我已经在我们的 JavaScript 应用程序中成功完成了此操作,但我在将其集成到我们的一些 Umbraco 网站中时遇到了一些困难。到目前为止我的代码:using System;using System.Threading.Tasks;using System.Net.Http;using System.Net.Http.Headers;using System.Web;using System.Web.Http;using Newtonsoft.Json;using System.Collections.Generic;using Umbraco.Web;using Umbraco.Web.WebApi;namespace Umbraco.WebApi{  public class TestController : UmbracoApiController  {    public  HttpClient client = new HttpClient();    [HttpPost]    public async Task<Object> GetRefreshToken(Token t)    {      try {        string refToken = t.refresh_token;        var values = new Dictionary<string, string>        {          { "grant_type", "refresh_token" },          { "client_id", "CLIENTID" },          { "client_secret", "CLIENTSECRET" },          { "refresh_token", refToken }        };        var content = new FormUrlEncodedContent(values);                var response = await client.PostAsync("https://URL.org/Token", content);        string responseString = await response.Content.ReadAsStringAsync();        return responseString;      } catch(HttpRequestException e) {        return e;      }    }    public class Token    {      public string refresh_token { get; set; }    }    public class AuthData    {      public string access_token { get; set; }      public string token_type { get; set; }      public int expires_int { get; set; }      public string refresh_token { get; set; }      public string userName { get; set; }      public string client_id { get; set; }      public DateTime issued { get; set; }      public DateTime expires { get; set; }    }  }}它确实成功返回了我想要的数据,但返回的数据存在问题(删除了敏感数据):<z:anyType xmlns:d1p1="http://www.w3.org/2001/XMLSchema" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" i:type="d1p1:string"></z:anyType>它似乎也以 XML 而不是 JSON 的形式返回?C# 不是我最擅长的语言,所以我可能完全错了。
查看完整描述

3 回答

?
catspeake

TA贡献1111条经验 获得超0个赞

在您的代码中,获取 JSON 字符串后responseString,不要返回它,而是尝试以下代码。


...

string responseString = await response.Content.ReadAsStringAsync();

response = Request.CreateResponse(HttpStatusCode.OK);

response.Content = new StringContent(responseString, Encoding.UTF8, "application/json");

return response;

您需要将方法返回值从 Task<Object> 更改为 Task<HttpResponseMessage>


编辑:


要访问属性,请安装 Newtonsoft.Json 包并尝试以下代码。


var jsonString = ...

JObject jo = JObject.Parse(jsonString);

Console.WriteLine(jo["access_token"]);


查看完整回答
反对 回复 2023-12-17
?
浮云间

TA贡献1829条经验 获得超4个赞

要解决此问题,您可以执行的操作之一是通过添加正确的请求标头来专门请求响应中的 json 格式

Accept: application/json

像这样尝试一下

client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

现在,如果服务器关注请求标头,它将返回一个 json 给您。 它可能默认为 xml,因为您的请求中没有此类标头,或者服务器仅支持返回 xml 响应。

编辑:如果您无法让服务器返回 json,您可以将 xml 字符串响应转换为 json 字符串。转换后,您可以从控制器正常返回 json 字符串。

编辑:

好的,尝试下面的示例:

var content = new FormUrlEncodedContent(new[]

                {

                new KeyValuePair<string, string>("client_id", ""),

                new KeyValuePair<string, string>("scope", ""),

                new KeyValuePair<string, string>("grant_type", "authorization_code"),

                new KeyValuePair<string, string>("redirect_uri", ""),

                new KeyValuePair<string, string>("code", ""),

                new KeyValuePair<string, string>("client_secret","")

            });


            AADTokenResponse TokenResponse = null;

            string _baseAddress = string.Format("https://yourTargetDomain.com/");


            using (var client = new HttpClient())

            {

                client.BaseAddress = new Uri(_baseAddress);

                client.DefaultRequestHeaders.Accept.Clear();

                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));


                var responseMessage = await client.PostAsync("targetApiSegment", content);


                if (responseMessage.IsSuccessStatusCode)

                {

                    var responseString = await responseMessage.Content.ReadAsStringAsync();

                    TokenResponse = JsonConvert.DeserializeObject<AADTokenResponse>(responseString);

                }

            }


查看完整回答
反对 回复 2023-12-17
?
米脂

TA贡献1836条经验 获得超3个赞

我认为在这种情况下,FormUrlEncodedContent是错误的选择,你应该使用StringContent,类似于:< /span>

var content = new StringContent(HttpUtility.UrlEncode(values), Encoding.UTF8, "application/json");
var response = await client.PostAsync("https://URL.com/Token", content);

原因是,我认为 FormUrlEncodeContent 没有重载来接受添加内容类型。

另一种替代方法是改用 SendAsync 而不是 PostAsync,因为 SendAsync 具有一些额外的灵活性。


查看完整回答
反对 回复 2023-12-17
  • 3 回答
  • 0 关注
  • 152 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信