带有图像和正文的 C# RESTful POST

Posted

技术标签:

【中文标题】带有图像和正文的 C# RESTful POST【英文标题】:C# RESTful POST with image and body 【发布时间】:2018-06-20 02:45:06 【问题描述】:

我目前正在尝试将一些数据发布到服务器以创建用户配置文件。 RESTful POST 的 body 已经选择了 image 和其他字段。

我设法使用 Postman 发布它。但是,我试图弄清楚如何使用 C# 来做到这一点。我尝试过,但似乎服务器返回状态 500 并没有太多有用的消息。

请参阅有关我如何 POST 到服务器的附件和一些有关我如何尝试 POST 的 C# 代码。感谢有关如何修复我的 C# 代码以使其正常工作的帮助。

C#代码:

if (!string.IsNullOrEmpty(baseUrl) && !string.IsNullOrEmpty(apiKey))
        
            var fullUrl = baseUrl + "/user_profiles";
            using (var httpClient = new HttpClient())
            
                //httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", apiKey);
                httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + apiKey);
                var boundary = "Upload----" + DateTime.Now.Ticks.ToString();

                using (var content = new MultipartFormDataContent(boundary))
                
                    try
                    
                        var name = string.IsNullOrEmpty(userRegistration.Name) ? "" : userRegistration.Name;
                        var city = string.IsNullOrEmpty(userRegistration.City) ? "" : userRegistration.City.ToUpper();
                        var phone = string.IsNullOrEmpty(userRegistration.Mobile) ? "" : userRegistration.Mobile;
                        phone = phone.Replace(" ", ""); //remove empty string in between and at edges
                        phone = phone.StartsWith("+") ? phone : "+" + phone;
                        var address = string.IsNullOrEmpty(userRegistration.CompanyAddress) ? "Unspecified" : userRegistration.CompanyAddress;
                        var country = string.IsNullOrEmpty(userRegistration.Country) ? "" : userRegistration.Country.ToUpper();
                        var email = string.IsNullOrEmpty(userRegistration.Email) ? "" : userRegistration.Email;
                        var isContractor = userRegistration.IsRegisteredAsContractor.ToString();
                        var category = string.IsNullOrEmpty(userRegistration.Category) ? "" : userRegistration.Category;
                        var companyName = string.IsNullOrEmpty(userRegistration.CompanyName) ? "" : userRegistration.CompanyName;
                        var companyAddress = string.IsNullOrEmpty(userRegistration.CompanyAddress) ? "" : userRegistration.CompanyAddress;

                        //TEST
                        //var body = new
                        //
                        //    city,
                        //    phone,
                        //    address,
                        //    country,
                        //    email,
                        //    name,
                        //    identifier_for_vendor = localId,
                        //    is_contractor = isContractor,
                        //    work_categories = category,
                        //    company_name = companyName,
                        //    company_address = companyAddress
                        //;

                        //var bodyStr = JsonConvert.SerializeObject(body);
                        //var stringContent = new StringContent(bodyStr, Encoding.UTF8, "application/json");

                        //content.Add(stringContent);
                        //response = await httpClient.PostAsync(fullUrl, content).ConfigureAwait(false);
                        //TEST

                        content.Add(new StringContent(name, Encoding.UTF8, "text/plain"), "name");
                        content.Add(new StringContent(city, Encoding.UTF8, "text/plain"), "city");
                        content.Add(new StringContent(phone, Encoding.UTF8, "text/plain"), "phone");
                        content.Add(new StringContent(companyAddress, Encoding.UTF8, "text/plain"), "address");
                        content.Add(new StringContent(country, Encoding.UTF8, "text/plain"), "country");
                        content.Add(new StringContent(email, Encoding.UTF8, "text/plain"), "email");
                        content.Add(new StringContent(localId, Encoding.UTF8, "text/plain"), "identifier_for_vendor");
                        content.Add(new StringContent(isContractor, Encoding.UTF8, "text/plain"), "is_contractor");
                        content.Add(new StringContent(category, Encoding.UTF8, "text/plain"), "work_categories");
                        content.Add(new StringContent(companyName, Encoding.UTF8, "text/plain"), "company_name");
                        content.Add(new StringContent(companyAddress, Encoding.UTF8, "text/plain"), "company_address");

                        if (!string.IsNullOrEmpty(userRegistration.ProfileImagePath) && File.Exists(userRegistration.ProfileImagePath))
                        
                            using (var stream = File.OpenRead(userRegistration.ProfileImagePath))
                            
                                //stream.Seek(0, SeekOrigin.Begin);
                                var fileName = Guid.NewGuid().ToString() + ".jpg";
                                content.Add(new StreamContent(stream), "image", fileName);
                                response = await httpClient.PostAsync(fullUrl, content).ConfigureAwait(false);
                            
                        
                        else
                        
                            response = await httpClient.PostAsync(fullUrl, content).ConfigureAwait(false);
                        
                    
                    catch (Exception ex)
                    

                    
                
            
        

【问题讨论】:

【参考方案1】:

当你使用File.OpenRead时,它会返回一个文件流(字节) 您需要将其转换为 Base64,这是通过 REST 发送图像的首选方式。

base64Image = System.Convert.ToBase64String(stream);

之后,您需要将其转换回后端并将其存储在您想要的任何位置。

另外,我不建议使用 FormDataContent 来发送数据,因为它有一些大小限制。

我建议使用JObject并将您要发送的内容添加为JProperty

Uri postURL = new Uri(Constants.RestUrl + "/NewReservation");
HttpClient client = new HttpClient();
TimeSpan timeout = new TimeSpan(0, 0, 20);
client.Timeout = timeout;                   

var UserData = AccountCheck.CurrentUserData();

JObject RequestData = new JObject(
    new JProperty("apiKey", UserData.ApiKey),
    new JProperty("customerID", UserData.CustomerId.ToString()),
    new JProperty("containerIDs", NewReservationRequest.ContainerIDs),
    new JProperty("containersQuantities", NewReservationRequest.ContainerQuantities),
    new JProperty("location", NewReservationRequest.Location),
    new JProperty("image", NewReservationRequest.ImageBlob),
    new JProperty("dateFrom", NewReservationRequest.StartDate.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture)),
    new JProperty("dateTo", NewReservationRequest.StartDate.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture)),
    new JProperty("expectedTime",NewReservationRequest.ExpectedTime),
    new JProperty("remarks", UserRemarks)
                );


var RequestDataString = new StringContent(RequestData.ToString(), Encoding.UTF8, "application/json");

HttpResponseMessage responsePost = await client.PostAsync(postURL, RequestDataString);
string response = await responsePost.Content.ReadAsStringAsync();

之后,您将需要解析 json 响应。 如果您需要更多帮助,请回复此答案

【讨论】:

您能否提供一个使用 FormDataContent 进行推荐的简单示例?我的目标是向服务器发布一个既有图像二进制文件又有要求字段的正文(请参阅 Postman 截图)。 你需要类似这个网站的东西来将图像转换为base64并将其作为json放入FormData codebeautify.org/image-to-base64-converter FormData 在邮递员中使用起来很简单,但是在 C# 中发送大图像时出现了一些异常 感谢代码示例。因此,根据您的示例,“NewReservationRequest.ImageBlob”的值基本上是图像流的转换版本,即字节数组?还是字节数组的“.ToString()”? 这是base64String作为答案的开始 base64Image = System.Convert.ToBase64String(stream);

以上是关于带有图像和正文的 C# RESTful POST的主要内容,如果未能解决你的问题,请参考以下文章

HttpClient postasync,带有自定义标头和应用程序/json,用于正文 C#

使用 C# 将图像添加到电子邮件正文

来自 Azure 函数的 C# HttpClient POST 请求,带有用于第三方 API 的授权标记,被剥离了标头和正文

在电子邮件正文中发送带有动态内容的图像

使用 c# windows 应用程序在电子邮件正文中添加多个图像(内联)

asp.net C# 如何以编程方式更改 Page_Load 上的正文背景图像