【问题标题】:Bad request when trying to post to rest service with byte[] input尝试使用 byte[] 输入发布到休息服务时出现错误请求
【发布时间】:2017-05-15 14:41:59
【问题描述】:

我尝试了很多不同的方式发布,但还没有进一步。我现在的解决方案返回以下错误消息:

传入的消息具有意外的消息格式“原始”。这 该操作的预期消息格式为“Xml”; '杰森'。这个可以 是因为没有配置 WebContentTypeMapper 捆绑。有关更多信息,请参阅 WebContentTypeMapper 的文档 详情。

RestService 方法:

[WebInvoke(Method = "POST",ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "UploadUser/{sessionID}/{Name}")]
    [OperationContract(Name = "UploadUser")]
    string UploadUser(string sessionID, string name, byte[] image);

尝试发布到服务:

 client = new HttpClient();
 client.MaxResponseContentBufferSize = 256000;
 client.DefaultRequestHeaders.Clear();
 client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
 client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
 client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/html"));

 public async Task<string> SaveUserItemAsync(User item, bool isNewItem = false)
 {
     try
     {
         var RestUrl = "http://192.168.240.127:55642/RestServiceImpl.svc/UploadUser/{0}/{1}";

         var uri = new Uri(string.Format(RestUrl, item.Id, item.Name));

         var base64String = Convert.ToBase64String(item.Thumbnail, 0, item.Thumbnail.Length);
         var jsonStr = JsonConvert.SerializeObject(base64String);   
         var messageBytes = System.Text.Encoding.UTF8.GetBytes(jsonStr);     

         var cont = new ByteArrayContent(messageBytes);
         cont.Headers.ContentType= MediaTypeHeaderValue.Parse("text/plain");
         //also tried cont.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");

         //also tried sending it as stringcontent
         //var json = JsonConvert.SerializeObject(item.Thumbnail);
         //var content = new StringContent(json, Encoding.UTF8, "application/json");              

         //also tried multipartcontent with no luck
         //var multipartContent = new MultipartFormDataContent();
         //multipartContent.Add(cont, "image");

         if (isNewItem)
         {

            var response = await client.PostAsync(uri, cont).ConfigureAwait(false);
            if (response.IsSuccessStatusCode)
            {
               var res = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
               return res;
               Debug.WriteLine(@"User successfully saved.");

            }
        }

     }
     catch (Exception ex)
     {

     }
}

当使用 cont.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");

我收到另一个错误消息:

反序列化操作请求消息正文时出错 '上传用户'。 OperationFormatter 遇到无效的消息正文。 预计会找到名称为“类型”且值为“对象”的属性。 找到值“字符串”。

Wireshark 显示:

将发送方法更改为:

 var senderPackage = new Dictionary<string, byte[]>
                {
                    {"image", messageBytes}
                };               
                var json = JsonConvert.SerializeObject(senderPackage);
                var content = new StringContent(json, Encoding.UTF8, "application/json");

出现新错误:

格式化程序在尝试反序列化 消息:尝试反序列化参数时出错 http://tempuri.org/:image。 InnerException 消息是“有 反序列化 System.Byte[] 类型的对象时出错。末端元件 来自命名空间“”的“图像”应为预期。找到的文字 'Ii85ai80QUFRU2taSlJnQUJBUUFBQVFBQkFBRC8yd0JEQUJzU0ZCY1VFUnNYRmhjZUhCc2dLRUlyS0NVbEtGRTZQVEJDWUZWbFpGOVZYVnRxZUptQmFuR1FjMXRkaGJXR2tKNmpxNjJyWjRDOHlicW14NW1vcTZULzJ3QkRBUndlSGlnaktFNHJLMDZrYmwxdXBLU2twS1NrcEtTa3BLU2twS1NrcEtTa3BLU2twS..

Wireshark 数据包看起来像这样:

如果有人知道如何让它发挥作用,我将永远欠你的债;)

【问题讨论】:

  • 工作解决方案: var json = "{ \"image\": [" + string.Join(",", item.Thumbnail) + "] }"; var content = new StringContent(json); content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); var response = await client.PostAsync(uri, content).ConfigureAwait(false);

标签: c# rest post


【解决方案1】:

您应该在 JSON 的请求标头中使用“application/json”作为媒体类型。

试试:

  • cont.Headers.ContentType= MediaTypeHeaderValue.Parse("application/json");
  • RequestFormat = WebMessageFormat.Json 给你的interface
  • 正文应包含一个键“图像”,其值为字节列表。

     1. Make a dictionary with key "image" and with value array of bytes. 
     2. Serialize the dictionary to Json
     3. Use StringContent insead of ByteArray Content
    

【讨论】:

  • 是的,我不知道该怎么做,但我尝试将其添加为 var multipartContent = new MultipartFormDataContent(); multipartContent.Add(续,“图像”);那没有用..我应该如何将数组链接到“图像”?
  • 也尝试过更改 BodyStyle = WebMessageBodyStyle.Bare,但这也没用
  • 你能发布你的json字符串吗
  • 使用新的wireshark 软件包图像更新问题
  • 你的值好像是一个字符串,它必须是一个字节数组
【解决方案2】:

我最终通过创建自己的 DataContract 并将其作为流发送来让它工作。插入代码以防任何人最终遇到与我相同的问题。

[DataContract]
    public class UploadObject
    {
        [DataMember(Name = "image")]
        public byte[] image { get; set; }

    }

休息服务方法:

  [OperationContract(Name = "UploadUser")]
        [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "UploadUser/{sessionID}/{Name}")]
        string UploadUser(string sessionID, string name, Stream image);

发帖休息:

public async Task<string> SaveUserItemAsync(User item, bool isNewItem = false)
        {
            try
            {
                var RestUrl = "http://192.168.240.127:55642/RestServiceImpl.svc/UploadUser/{0}/{1}";

                var uri = new Uri(string.Format(RestUrl, item.Id, item.Name));
                UploadObject obj = new UploadObject();
                obj.image = item.Thumbnail;

                var json = JsonConvert.SerializeObject(obj);
                var stream = new MemoryStream(Encoding.UTF8.GetBytes(json));

                var content = new StreamContent(stream);
                content.Headers.ContentLength = stream.Length;

                if (isNewItem)
                {

                    var response = await client.PostAsync(uri, content).ConfigureAwait(false);
                    if (response.IsSuccessStatusCode)
                    {
                        var res = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                        return res;                       
                    }

                    return "success";
                }

            }
            catch (Exception ex)
            {

            }
            return "Failure";
        }

几天后,服务开始抱怨它不能接受多个参数以及流输入,所以我将它改回接收字节数组,并通过创建我自己的 jason 并以这种方式格式化字节数组来设法让它工作:

 var json = "{ \"image\": [" + string.Join(",", item.Thumbnail) + "] }";

 var content = new StringContent(json);
 content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
 var response = await client.PostAsync(uri, content).ConfigureAwait(false);

【讨论】:

    猜你喜欢
    • 2011-06-05
    • 2018-10-03
    • 2019-09-05
    • 1970-01-01
    • 2019-10-10
    • 2013-11-27
    • 1970-01-01
    • 2013-05-04
    • 1970-01-01
    相关资源
    最近更新 更多