【问题标题】:Post from xamarin to restful API从 xamarin 发布到 restful API
【发布时间】:2021-06-19 17:35:57
【问题描述】:

我正在尝试从 xamarin 进行 API 调用,这是我第一个使用 Angular WebApp 调用 restful API (.NetCore3.1) 的完整移动应用程序。 来自 xamarin 应用程序的所有其他 API 调用都在工作, 问题是我需要发送一个带有对象的文件,文件可以是 .doc .png 等。

GrantApplication.cs API端点

    public class FileProvider
    {
        public string GA { get; set; }
        public IList<IFormFile> Files { get; set; }
    }


         [HttpPost]
        [Route("[action]")]
        public ActionResult SubmitGrantApplication([FromForm] FileProvider fileProvider)
        {
            try
            {
                var ga = fileProvider;
                byte[] fileContent = null;
                var files = Request.Form.Files.Any() ? Request.Form.Files : new FormFileCollection();
                var grant = JsonConvert.DeserializeObject<GrantApplication>(ga.GA);
               ...
            }
        }

GrantService.cs 从移动应用程序拨打电话: 此调用返回 400 响应,但没有明确说明原因。 我正试图找出原因,而且我的邮递员技能并没有那么好,无法将代码转换为邮递员。

#5 处返回的错误。
::"对象引用未设置为对象的实例。"

public class GrantService
    {
        public static async Task<GrantApplication> SubmitGrant(GrantApplication ga,string file, string FileName, StreamContent FileData)
        {
                Uri requestUri = new Uri($"{ApiSettings.ApiBaseUrl}/grantapplication/SubmitGrantApplication");
                try
                {
                    var upfilebytes = File.ReadAllBytes(file);
                    //using (HttpClient client = new HttpClient())
                    //{
                    //    //MultipartFormDataContent content = new MultipartFormDataContent();
                    //    //ByteArrayContent baContent = new ByteArrayContent(upfilebytes);
                    //    //StringContent GA = new StringContent(JsonConvert.SerializeObject(ga));
                    //    //content.Add(baContent, "Files", FileName);
                    //    //content.Add(GA, "GA");
                    //    //Console.WriteLine(content);
                    //    //var response = await client.PostAsync(requestUri, content);
                    //    //Console.WriteLine(await response.Content.ReadAsStringAsync());
                    //    //return ga;
                    //}
                    using (var formContent = new MultipartFormDataContent())
                    {
                        formContent.Headers.ContentType.MediaType = "multipart/form-data";
                        // 3. Add the filename C:\\... + fileName is the path your file
                        Stream fileStream = File.OpenRead(file);
                        formContent.Add(new StreamContent(fileStream), FileName, FileName);
                        var payload = JsonConvert.SerializeObject(ga);
                        HttpContent content = new StringContent(payload, Encoding.UTF8, "application/json");
                        formContent.Add(content, "GA");
                        using (var client = new HttpClient())
                        {
                            // Bearer Token header if needed
                            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("multipart/form-data"));

                            try
                            {
                                // 4.. Execute the MultipartPostMethod
                                var message = await client.PostAsync(requestUri, formContent);
                                // 5.a Receive the response
                                var result = await message.Content.ReadAsStringAsync();
                                Console.WriteLine(result);
                            }
                            catch (Exception ex)
                            {
                                // Do what you want if it fails.
                                throw ex;
                            }
                        }
                    }
                    return ga;
                }
                catch(Exception ex)
                {
                     Console.WriteLine(ex);
                    return ga;
                }
           
        }
    }

网络系统 Angular API 调用

public SubmitGrantApplication(grantApplication){
    grantApplication.memberId = JSON.parse(sessionStorage.getItem("LoggedInUser")).memberID;
    grantApplication.ClientID = JSON.parse(sessionStorage.getItem("LoggedInUser")).clientID;
    this.headers = new HttpHeaders({ 'Content-Type' :  'multipart/form-data' });
    this.headers = new HttpHeaders({ 'Accept':  'multipart/form-data'});
    let myFormData: FormData = new FormData();
    myFormData.append("Files", grantApplication.documentContent);
    myFormData.append("GA", JSON.stringify(grantApplication));
    return this.http.post<GrantApplication>(this.url+"SubmitGrantApplication", myFormData , { headers: this.headers }).pipe(
    ).toPromise();
  }
  

大摇大摆

Swagger Doc

作品 Angular API Call 作品 Payload Angular

【问题讨论】:

  • 只是一个友好的建议;使用 API 时,您可能希望首先使用 Postman 测试您的端点,尤其是当您遇到问题时。 BR
  • 在角度端点工作得非常好,有没有办法可以将我的 Visual Studio xamarin 项目指向我运行调试版本的本地主机端口?注意我只遇到来自 xamarin 方面的问题,试图发布多部分 IFormFile 部分是我认为的障碍
  • 请注意,这是我写的第一个应用程序和网络应用程序,以使用一个 .netcore restfull 服务
  • 您应该使用适用于 Angular 的信息更新您的问题。让我们等待 Xamarin 人解决这个问题。 BR
  • @JohnathanFourie 您在 GrantService.cs 中哪里得到 400 错误?从您的错误消息来看,您似乎需要一个对象的实例。

标签: c# xamarin .net-core xamarin.android


【解决方案1】:

我尝试使用相同的代码复制您的案例(未使用的代码已删除)

它有效,你能分享 PostAsync 的整个响应吗? url、响应码和其他属性可以告诉我们一些事情

    public static async Task<dynamic> SubmitGrant(object ga, string file, string FileName)
    {
        var upfilebytes = File.ReadAllBytes(file);
        using (HttpClient client = new HttpClient())
        {
            Uri requestUri = new Uri($"https://localhost:44341/grantapplication/SubmitGrantApplication");
            MultipartFormDataContent content = new MultipartFormDataContent();
            ByteArrayContent baContent = new ByteArrayContent(upfilebytes);
            StringContent GA = new StringContent(JsonConvert.SerializeObject(ga));
            content.Add(baContent, "Files", FileName);
            content.Add(baContent, "Files", 1 + FileName); /* test 2 files */
            content.Add(GA, "GA");
            Console.WriteLine(content);
            var response = await client.PostAsync(requestUri, content);
            Console.WriteLine(response);
            return ga;
        }
    }

调用方法

await SubmitGrant(new { Test = 123 }, "C:\\Temp\\MyPicture.jpg", "MyPicture.jpg");

接收数据和文件

【讨论】:

  • 尝试了代码,我得到了 400 响应,在某处我的有效负载或标头给了我一个问题。如果可能,我正在尝试将我的角度调用准确地复制到我的 API 端点
【解决方案2】:

这篇文章完美无缺,邮件功能中存在附加 API 接收到的文件的问题,文件属性设置不同,并且无法从 bytearray 附加文件... 修复了调用并在 API 中添加了抛出异常, 永远不要返回 BadRequest();在捕获部分。将抛出错误 400 而不是标准错误 500 服务器错误

【讨论】:

    猜你喜欢
    • 2014-09-11
    • 2018-12-23
    • 1970-01-01
    • 2017-05-17
    • 1970-01-01
    • 1970-01-01
    • 2013-05-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多