简体   繁体   English

C# Rest API 文件上传

[英]C# Rest API File upload

I am trying too upload a file with C# by an API.我也在尝试通过 API 上传带有 C# 的文件。

The StreamUtils dont work, I am getting error: "Cannot convert lambda expression to type 'string' because it is not a delegate type". StreamUtils 不起作用,我收到错误消息:“无法将 lambda 表达式转换为类型‘字符串’,因为它不是委托类型”。

Any idea on how to upload the file?关于如何上传文件的任何想法? It is around 100MB.它大约是 100MB。

 public void UploadModel(string ProjectId, string filename, Stream fileStream)
        {

            string access_token_string = Read_Json_Values("access_token");
            string webstring = String.Format("https://api.test.com/v2/projects/{0}/revisions", ProjectId);

            var client = new RestClient(webstring);
            client.Timeout = -1;
            var request = new RestRequest(Method.POST);
            request.AddHeader("Authorization", "Bearer " + access_token_string);
            request.AddHeader("Content-Type", "application/ifc");
            request.AddHeader("xxx-Params", "{\"callbackUri\": \"https://example.com\", \"filename\": \"mk337.ifc\", \"comment\": \"From Postman\", \"model\": \"21312312312312\"}");
            request.AddFile("file", s => StreamUtils.CopyStream(fileStream, s), filename);


            IRestResponse response = client.Execute(request);
            Console.WriteLine("Model is uploaded!");
        }
internal static class StreamUtils
        {
            private const int STREAM_BUFFER_SIZE = 128 * 1024; // 128KB

            public static void CopyStream(Stream source, Stream target)
            { CopyStream(source, target, new byte[STREAM_BUFFER_SIZE]); }

            public static void CopyStream(Stream source, Stream target, byte[] buffer)
            {
                if (source == null) throw new ArgumentNullException("source");
                if (target == null) throw new ArgumentNullException("target");

                if (buffer == null) buffer = new byte[STREAM_BUFFER_SIZE];
                int bufferLength = buffer.Length;
                int bytesRead = 0;
                while ((bytesRead = source.Read(buffer, 0, bufferLength)) > 0)
                    target.Write(buffer, 0, bytesRead);
            }

So you have two issues in your code ...所以你的代码中有两个问题......

1. Lambda expression issue 1. Lambda 表达式问题

The following line causes the lambda expression issue以下行导致 lambda 表达式问题

request.AddFile("file", s => StreamUtils.CopyStream(fileStream, s), filename);

// This is the function you want to call
void CopyStream(Stream source, Stream target)

So the issue is, that所以问题是,那

s => StreamUtils.CopyStream(fileStream, s)

is a Lambda expression, where you define s and give s as second Parameter to是一个 Lambda 表达式,您可以在其中定义 s 并将 s 作为第二个参数

CopyStream(Stream source, Stream target)

but s is not of type Stream.但 s 不是 Stream 类型。 That's why you get the exception.这就是为什么你会得到例外。

2. request.AddFile needs Parameters 2. request.AddFile 需要参数

Assuming you use the RestSharp NuGet package for your REST request (I assume that because the classes look like the once from RestSharp) you should have a look on the different overloads of RestRequest.AddFile():假设您将 RestSharp NuGet 包用于您的 REST 请求(我假设因为这些类看起来像来自 RestSharp 的一次),您应该看看 RestRequest.AddFile() 的不同重载:

AddFile(string name, string path, string contentType = null);
AddFile(string name, byte[] bytes, string fileName, string contentType = null);
AddFile(string name, Action<Stream> writer, string fileName, long contentLength, string contentType = null);

All functions need several parameters.所有函数都需要几个参数。 I guess you want to use the second definition which is我猜你想使用第二个定义

AddFile(string name, byte[] bytes, string fileName, string contentType = null);

So if we compare it with the line in your code因此,如果我们将其与代码中的行进行比较

request.AddFile("file", s => StreamUtils.CopyStream(fileStream, s), filename);

We see that you give following Parameters:我们看到您提供了以下参数:

  • "file" as the name “文件”作为名称
  • Function call (Lambda expression) for the bytes字节的函数调用(Lambda 表达式)
  • Filename variable for the filename文件名的文件名变量

The first and third parameters look good but second parameter is an issue.第一个和第三个参数看起来不错,但第二个参数有问题。

My suggestions:我的建议:

Define a secound stream parameter in your UploadModel and pass it to the CopyStream function:在您的 UploadModel 中定义第二个流参数并将其传递给 CopyStream 函数:

public void UploadModel(string ProjectId, string filename, Stream sourceStream, Stream targetStream)
{
    // .... your code still here, just want to show the changing lines
    request.AddFile("file", StreamUtils.CopyStream(sourceStream, targetStream), filename);
}

And if you still want to call StreamUtils.CopyStream() to get the second parameter for request.AddFile, you have to change the function definition as it currently returns void.如果您仍然想调用 StreamUtils.CopyStream() 来获取 request.AddFile 的第二个参数,您必须更改函数定义,因为它当前返回 void。 So instead of:所以而不是:

public static void CopyStream(Stream source, Stream target)
public static void CopyStream(Stream source, Stream target, byte[] buffer)

you have to change it to你必须把它改成

public static byte[] CopyStream(Stream source, Stream target)
public static byte[] CopyStream(Stream source, Stream target, byte[] buffer)

which leads us to the changes in the function body itself, as we now have to return a byte[] accordingly to the functions definition (this is just an example and still needs to get the real implementation which I am currently not able to do, just hope that it gives you an impression how to do it):这导致我们对函数体本身进行更改,因为我们现在必须根据函数定义返回一个 byte[](这只是一个示例,仍然需要获得我目前无法做到的真实实现,只是希望它给你一个印象如何去做):

public static byte[] CopyStream(Stream source, Stream target, byte[] buffer)
{
    // -> Define a byte array
    byte[] bytesToReturn;

    // -> Fill the array with data
    // ...

    // -> return the array
    return bytesToReturn;
}

With these changes it should work.通过这些更改,它应该可以工作。

I think you can convert your input file to Base64 and then send it.我认为您可以将输入文件转换为 Base64,然后发送。 See also the answers of other professors what they think.另请参阅其他教授的回答他们的想法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM