Upload Model with Data API and C#

Hey everyone!

I am working on a personal project where I am developing a plugin for Revit to upload a model or selection of elements.

I am struggling with creating in the correct way the MultipartFormDataContent in C#, as the Data API continues to throw a Bad Request error.

I am serializing a Sketchfab_Model object which you can see below:

internal class Sketchfab_Model
    {
        public string name { get; set; }
        public string description { get; set; }
        public IList<string> tags { get; set; }
        public IList<string> categories { get; set; }
        public string license { get; set; }
        public bool isPublished { get; set; }
        public bool isInspectable { get; set; }

        public Sketchfab_Model(string modelName)
        {
            name = modelName;
            description = "Uploaded with Ricardo Salas' Sketchfab Exporter Revit Plugin";
            tags = new List<string>()
            {
                "ricardosalasv.com",
                "revit",
                "revit API",
                "C#"
            };
            categories = new List<string>()
            {
                "Architecture"
            };
            license = "by Ricardo Salas";
            isPublished = false;
            isInspectable = true;
        }
    }

and the rest of the code goes as follows:

public async Task<string> UploadModel(string modelFilePath, string modelName)
        {
            // Creating an object that will be serialized, which contains relevant data for the Sketchfab API
            Sketchfab_Model modelObject = new Sketchfab_Model(modelName);

            // Model data content
            HttpContent content = new StringContent(JsonConvert.SerializeObject(modelObject));

            try
            {
                // Reading our model from disk and creating a stream to it in order to add it to the POST request
                var fileStream = File.OpenRead(modelFilePath);
                HttpContent streamContent = new StreamContent(fileStream);

                var formData = new MultipartFormDataContent();
                formData.Add(content, "data");
                formData.Add(streamContent, "modelFile", modelName);

                string test = await formData.ReadAsStringAsync();

                HttpResponseMessage responseMessage = await client.PostAsync(new Uri("https://api.sketchfab.com/v3/models", UriKind.Absolute), formData);

                var result = await responseMessage.Content.ReadAsStringAsync();

                fileStream.Close();

                return result;
            }
            catch (Exception ex)
            {
                string message = ex.Message;
            }


            return null;
        }

This is the value of the variable test:

--47175cfc-c103-4084-ae49-9190e2d99a12
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=data

{"name":"Test123","description":"Uploaded with Ricardo Salas' Sketchfab Exporter Revit Plugin","tags":["ricardosalasv.com","revit","revit API","C#"],"categories":["Architecture"],"license":"by Ricardo Salas","isPublished":false,"isInspectable":true}
--47175cfc-c103-4084-ae49-9190e2d99a12
Content-Disposition: form-data; name=modelFile; filename=Test123; filename*=utf-8''Test123

PK

I have experience with Python and have been trying to translate Sketchfab’s python code sample to C#, but I have definitely not had success

The final payload that is sent is not being correctly structured?

Thanks for your time and attention!

Regards.

Hi @ricardo.salas.cg,
I’m not seeing anything wrong with your request. I’m using C# too for the 3dsmax exporter, but admittedly my code is much older than yours. I’m doing things in a more primitive way.
What you could do is strip away all optional data from your Sketchfab_Model object and see where things break down.

1 Like

klaasnienhuis , your answer is correct I agree with you

Hey @klaasnienhuis , thank you so much for taking a look at this, I tried what you suggested and I detected that the problem was the part of adding the StreamContent to the MultipartFormDataContent object, and also because I reviewed the message obtained on the variable result, and I was receiving an error message from the API claiming that the format of the file was not supported.

As the majority of problems that eat your head often, this was very simple and funny, the modelName variable’s value was “ModelName” without the .zip extension.

Once I added that the Post method worked and now I am able of uploading models.

The code looks like this now.

public async Task<string> UploadModel(string modelFilePath, string modelName)
        {
            // Creating an object that will be serialized, which contains relevant data for the Sketchfab API
            Sketchfab_Model modelObject = new Sketchfab_Model(modelName);

            // Model data content
            HttpContent content = new StringContent(JsonConvert.SerializeObject(modelObject));

            try
            {
                // Reading our model from disk and creating a stream to it in order to add it to the POST request
                FileStream fileStream = new FileStream(modelFilePath, FileMode.Open, FileAccess.Read);
                HttpContent streamContent = new StreamContent(fileStream);
                var test2 = await streamContent.ReadAsStreamAsync();

                var formData = new MultipartFormDataContent();
                formData.Add(content, "data");
                formData.Add(streamContent, "modelFile", modelName + ".zip");

                string test = await formData.ReadAsStringAsync();

                HttpResponseMessage responseMessage = await client.PostAsync(new Uri("https://api.sketchfab.com/v3/models", UriKind.Absolute), formData);

                var result = await responseMessage.Content.ReadAsStringAsync();

                fileStream.Close();

                return result;
            }
            catch (Exception ex)
            {
                string message = ex.Message;
            }


            return null;
        }

Thank you so much!

2 Likes