0

I'm trying to save some data to my database and uploading an image at the same time using a Web Api.

I failed to do this because I cannot send multipart/from and JSON at the same time. I got this error:

request entity's media type 'multipart/form-data' is not supported for this resource.

This is my code:

public IHttpActionResult Post([FromBody]Post userpost)
{
   Upload upload = new Upload();
   int postid = Convert.ToInt32(postDB.AddPost(userpost));                   
   var filename = postid + "_"+Guid.NewGuid().ToString();
   upload.UploadFile(filename, Request);
   return Ok(HttpStatusCode.Accepted);
}

public class Upload:IUpload
{
    private const string Container = "images";

    public async Task<bool> UploadFile(string filename, HttpRequestMessage Request)
    {
        var accountName = ConfigurationManager.AppSettings["storage:account:name"];

        var accountKey = ConfigurationManager.AppSettings["storage:account:key"];
        var storageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true);
        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

        CloudBlobContainer imagesContainer = blobClient.GetContainerReference(Container);

        var provider = new AzureImages(imagesContainer,filename);

        try
        {
            await Request.Content.ReadAsMultipartAsync(provider);
        }
        catch (Exception ex)
        {
            return false;
        }

        if (string.IsNullOrEmpty(filename))
        {
            return false;
        }

        return true;
    }
}
}

I'm testing it using Postman Thanks in advance.

2
  • create a view model that has the information from Post and the image in either a byte[] or base64 string and HttpPost that to your controller action. Commented Mar 9, 2018 at 15:20
  • Thanks, but I don't know how to do this. Please help Commented Mar 9, 2018 at 15:34

1 Answer 1

1

create a view model to handle your entire posted information.

public class CombinedPostAndImage
{
    /* your post properties */
    public intProperty1 { get;set; }
    public string Propert2 { get;set; }
    ...
    public string FileName { get; set; }
    /* this example is using a Base64String
    public string FileBody { get; set; }
}

change your controller action to accept this new type.

public IHttpActionResult Post(CombinedPostAndImage combinedPost)
{
  /* create your Post from the combinedPost  */
    var post = new Post
    {
        post.Property1 = combinedPost.Property1,
        /* more properties */
    };

    int postid = Convert.ToInt32(postDB.AddPost(userpost));

    var filename= string.Format("{0}_{1}", postid, Guid.NewGuid().ToString());

        //Convert Base64 Encoded string to Byte Array.
    using (var ms = new MemoryStream(Convert.FromBase64String(combinedPost.FileBody)))
    {
        var uploader = new Upload();
        uploader.UploadFile(filename, ms);
    }
}

Per you update I would change the UploadFile method to take a stream. Like

public async Task<bool> UploadFile(string filename, Stream uploadStream)
{       
   var accountName = ConfigurationManager.AppSettings["storage:account:name"];

    var accountKey = ConfigurationManager.AppSettings["storage:account:key"];
    var storageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true);
    CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
    CloudBlobContainer imagesContainer = blobClient.GetContainerReference(Container);

    CloudBlockBlob blockBlob = imagesContainer.GetBlockBlobReference(filename);

    blockBlob.UploadFromStream(uploadStream);
}  

I'm not familiar with the Azure SDK, but from the documentation online, you probably want something like this.

I wouldn't tie my Azure uploader to the Request stream. I'd also pass the Upload(er) class to my controller's constructor since it a required dependency that can be satisfied through an IoC container.

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

1 Comment

I posted the Upload Class. I will post images to Azure. I will use Jquery to call this web api

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.