0

I am trying too upload a file with C# by an API.

The StreamUtils dont work, I am getting error: "Cannot convert lambda expression to type 'string' because it is not a delegate type".

Any idea on how to upload the file? It is around 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);
            }
6
  • I can assume this line request.AddFile("file",s=>StreamUtils.CopyStream(fileStream, s), filename); throws an Exception, but clarification is needed. Commented Feb 14, 2020 at 13:47
  • The line request.AddFile("file", s => StreamUtils.CopyStream(fileStream, s), filename) is causing the issue because "s => StreamUtils.CopyStream(fileStream, s)" is a lambda expression and not a stream. What you have to do is to define a target Stream as expected in the function StreamUtils.CopyStream(Stream source, Stream target) Commented Feb 14, 2020 at 13:48
  • It looks like your call to request.AddFile() does not match any of the method signatures available: see this link for clarification. Commented Feb 14, 2020 at 13:55
  • Does this help? It provides answers of how to upload a file using RestSharp stackoverflow.com/questions/32876606/… Commented Feb 14, 2020 at 13:58
  • @rekcul Hey, can you provide an sample code? Commented Feb 17, 2020 at 7:58

2 Answers 2

1

So you have two issues in your code ...

1. Lambda expression issue

The following line causes the lambda expression issue

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

CopyStream(Stream source, Stream target)

but s is not of type Stream. That's why you get the exception.

2. request.AddFile needs Parameters

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():

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
  • 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:

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. 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):

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.

Sign up to request clarification or add additional context in comments.

Comments

-3

I think you can convert your input file to Base64 and then send it. See also the answers of other professors what they think.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.