【问题标题】:Return a byte[] array from controller class in ASP.NET从 ASP.NET 中的控制器类返回一个 byte[] 数组
【发布时间】:2016-08-15 03:46:24
【问题描述】:

我有一个控制器类(在C# 中),它必须从其登录方法返回一个字节数组。请为我的登录功能找到我的控制器类的以下源代码。

[RoutePrefix("Account")]
    public class AccountsController : ApiController     
    {
        [Route("Login")]
        [HttpPost]   
        public byte[] Login()
        {
            byte[] mSessionID = new Session().getmSessionID();
            return mSessionID;
        }
    }

在测试时,Web 服务返回一个 base64Encoded 字符串值作为“LVpgqWBYkyXX1FlDg95vlA==”。我希望我的 Web 服务返回一个字节数组响应(在 JSON 响应中)。

【问题讨论】:

  • 看起来您使用的是 ASP.NET 5 WebApi 或更低版本。正确的?默认情况下,WebAPI 以 Base64 编码返回 byte[]。您可以更改返回响应的方式,但您希望如何查看信息?它应该是 JSON 对象中的十六进制值数组吗?还是应该是八位字节流响应?请提供您希望 API 返回的示例。
  • 我不知道这两种格式。但我想要的格式应该如下所示: {Numbers : 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 11, 12, 13, 14, 15,2,45 } ; .我希望 Web 服务本身返回一个字节数组

标签: c# arrays json byte


【解决方案1】:

如果你想得到这种格式的响应:

{
  "Numbers": [
    2,
    3,
    4,
    5,
    6,
    7,
    8,
    9,
    10,
    1,
    11,
    12,
    13,
    14,
    15,
    2,
    45
  ]
}

解决方案 1:JSON 格式化程序

您需要修改 JSON 的序列化方式。 WebAPI 使用 JSON.Net unser 将 WebAPI 响应格式化为 JSON。我们可以按如下方式覆盖 byte[] 格式化程序:

创建自定义格式化程序

public class ByteArrayFormatter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(byte[]);
    }
    public override bool CanRead
    {
        get
        {
            return false;
        }
    }
    public override bool CanWrite
    {
        get
        {
            return true;
        }
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var byteArray = (byte[])value;
        writer.WriteStartArray();
        if (byteArray != null && byteArray.Length > 0)
        {
            foreach (var b in byteArray)
            {
                writer.WriteValue(b);
            }
        }
        writer.WriteEndArray();
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

Global.asax.csApplication_Start 方法中全局注册格式化程序(注意所有byte[] 类型都将以这种方式序列化):

var formatters = GlobalConfiguration.Configuration.Formatters;
var jsonFormatter = formatters.JsonFormatter;
jsonFormatter.SerializerSettings.Converters.Add(new ByteArrayFormatter());

创建一个模型,以便您的 JSON 响应具有 Numbers 属性:

public class NumbersModelByte
{
    public byte[] Numbers { get; set; }
}

修改您的控制器以使用此模型:

[Route("login")]
[System.Web.Http.AcceptVerbs("GET")]
[System.Web.Http.HttpGet]
public NumbersModelByte Login()
{
    byte[] mSessionID = new Session().getmSessionID();
    return new NumbersModelByte
    {
        Numbers = mSessionID
    };
}

解决方案 2:又快又脏

您需要返回一个对象(模型)。

NumbersModelInt.cs(注意 int[] 类型)

public class NumbersModelInt
{
    public int[] Numbers { get; set; }
}

然后您需要将字节数组中的所有字节转换为响应中的整数:

[Route("Login")]
[HttpPost]   
public byte[] Login()
{
    byte[] mSessionID = new Session().getmSessionID();
    return new NumbersModelInt
    {
        Numbers = mSessionID.Select(b => (int) b).ToArray()
    };
}

【讨论】:

  • 没问题。告诉我进展如何
  • 谢谢 Joao.. 我尝试了第一个选项,效果很好.. 非常感谢.. 我为此苦苦挣扎了一段时间,对如何在 C# 中实现有了更清晰的了解(我是新手).. 干杯...
  • 不用担心。很高兴能够提供帮助
【解决方案2】:

回答我的第二个问题。 (将 JSON 对象传递给 Controller 的方法)

我得到了同事的帮助,她找到了正确的链接。

https://weblog.west-wind.com/posts/2013/dec/13/accepting-raw-request-body-content-with-aspnet-web-api....

我为解决此问题所做的代码更改是

公共异步任务登录() { 字符串输入 = 等待 Request.Content.ReadAsStringAsync();动态数据 = Newtonsoft.Json.Linq.JObject.Parse(input); }

(输入 - 返回为 JSON 格式的字符串) (数据 - 返回 JSON 对象)

【讨论】:

  • 我可以在 CanConvert 方法中从 ByteArrayFormatter.cs 返回一个 sbyte[]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-17
  • 2013-03-28
  • 1970-01-01
  • 2013-02-01
  • 2015-03-24
相关资源
最近更新 更多