POST附件和常规字段C#

时间:2017-01-23 10:35:14

标签: c# json

我正在使用C#。

我几乎没有问题:

  1. 我想知道什么是最好的"使用附件发出HTTP请求的方法

    我可以发送字典:{{" FileName":" a.txt",FileBase64Stream:" SOME BASE 64 STRING"},{&#34 ; FileName":" b.txt",FileBase64Stream:" SOME BASE 64 STRING"}}

    或者还有其他方式发送附件?

  2. 我想将一般对象(int,string等)作为json发送,我是按照以下方式进行的:

    {{" value":" 1.2"," type":" float"},{" value&# 34;:" 1","输入":" int"},{"值":"你好", "输入":" string"},{" value":" 00011111010101"," type":&#34 ;字节"}}

  3. 但在这种情况下,客户端需要根据类型转换值,还有另一种发送方式" general"对象作为JSON并解析它?

    Thakns

1 个答案:

答案 0 :(得分:0)

虽然Base64编码可能适用于小型有效负载,但对于较大的文件,它会增加太多的开销。我建议您使用multipart/form-data中定义的RFC 2388,因为它允许您直接将文件作为二进制流发送。大多数服务器端API框架都对multipart/form-data编码请求具有本机支持。这是一个示例有效载荷:

POST /upload HTTP/1.1
Host: example.com
Content-Type: multipart/form-data, boundary=AaB03x

--AaB03x
Content-Disposition: form-data; name="file1"; filename="a.txt"
Content-Type: text/plain

contents of a.txt come here
--AaB03x
Content-Disposition: form-data; name="file2"; filename="b.txt"
Content-Type: text/plain

contents of b.txt come here
--AaB03x--

关于关于反序列化通用对象的第二个问题,Json.NET包允许您编写自定义JsonConverter来处理这种情况。您可以从建模数据开始:

public class MyModel
{
    public object Value { get; set; }

    public string Type { get; set; }
}

然后编写一个转换器来处理它:

public class MyConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(MyModel);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
        {
            return null;
        }

        var json = JObject.Load(reader);
        JToken typeToken;
        JToken valueToken;
        if (json.TryGetValue("type", StringComparison.InvariantCultureIgnoreCase, out typeToken) &&
            json.TryGetValue("value", StringComparison.InvariantCultureIgnoreCase, out valueToken))
        {
            string type = typeToken.Value<string>().ToLowerInvariant();
            var model = new MyModel();
            model.Type = type;
            switch (type)
            {
                case "float":
                    model.Value = valueToken.Value<float>();
                    break;
                case "int":
                    model.Value = valueToken.Value<int>();
                    break;
                case "string":
                    model.Value = valueToken.Value<string>();
                    break;
                case "bytes":
                    string input = valueToken.Value<string>();
                    int count = input.Length / 8;
                    byte[] bytes = new byte[count];
                    for (int i = 0; i < count; ++i)
                    {
                        bytes[i] = Convert.ToByte(input.Substring(8 * i, 8), 2);
                    }
                    model.Value = bytes;
                    break;
                default:
                    throw new NotSupportedException("The specified type is not supported: " + type);
            }

            return model;
        }

        return null;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

现在剩下的就是在反序列化时使用这个转换器:

string json =
@"[{
    ""value"": 1.2,
    ""type"": ""float""
  }, {
    ""value"": 1,
    ""type"": ""int""
  }, {
    ""value"": ""Hello"",
    ""type"": ""string""
  }, {
    ""value"": ""00011111010101"",
    ""type"": ""bytes""
  }]";
var myConverter = new MyConverter();
var models = JsonConvert.DeserializeObject<IList<MyModel>>(json, myConverter);