Unsupported media type when uploading using web ap

2019-08-09 17:52发布

问题:

I am currently migrating a service to utilise asp.net web api from mvc. I have this ApiController

[Authorize]
public class UploadController : ApiController
{
    private readonly ObjectService service;
    private readonly string companyId;

    public UploadController()
    {
        this.companyId = "D49AA22B-3476-4FAC-8BEF-38F53F9378F3";
        this.service = new ObjectService(ConfigurationManager.AppSettings["AWSAccessKey"], ConfigurationManager.AppSettings["AWSSecretKey"], this.companyId);
    }

    // POST api/upload/5
    [HttpPost]
    [Route("api/upload")]
    public IHttpActionResult StartUpload(UploadModel model)
    {
        try
        {
            var id = Guid.NewGuid().ToString();

            if (!service.Exists(model.File.FileName))
            {
                service.Add(id);

                var stream = new MemoryStream();
                var caller = new AsyncMethodCaller(service.Upload);

                model.File.InputStream.CopyTo(stream);

                var result = caller.BeginInvoke(id, stream, model.File.FileName, new AsyncCallback(CompleteUpload), caller);
            }
            else
                throw new Exception("This file already exists. If you wish to replace the asset, please edit it.");

            return Ok(id);
        }
        catch (Exception ex)
        {
            return InternalServerError(ex);
        }
    }

    public void CompleteUpload(IAsyncResult result)
    {
        var caller = (AsyncMethodCaller)result.AsyncState;
        var id = caller.EndInvoke(result);

        //this.service.Remove(id);
    }

    // GET api/upload/progress/5
    [HttpGet]
    [Route("api/upload/progress/{id}")]
    public IHttpActionResult GetCurrentProgress(string id)
    {
        try
        {
            var progress = service.GetStatus(id);
            return Ok(progress);
        }
        catch (Exception ex)
        {
            return InternalServerError(ex);
        }
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
            this.service.Dispose();

        base.Dispose(disposing);
    }
}

As you can see, if I do a post to api/upload it should start to upload my file. These methods have been converted from an existing mvc Controller (which returned JsonResult instead of IHttpActionResult)

my UploadModel looks like this:

public class UploadModel
{
    public HttpPostedFileBase File { get; set; }
    public string FileName { get; set; }
}

and my jquery looks like this:

function uploadFile() {
    var file = $("#File")[0].files[0];

    if (file) {
        var fileName = "test/" + $('input[type=file]').val().split('\\').pop();
        var data = new FormData();

        data.append("File", file);
        data.append("FileName", fileName);

        $.ajax({
            url: "/Api/Upload",
            type: 'POST',
            data: data,
            contentType: false,
            processData: false,
            success: function (data) {
                console.log("uploading");
                console.log(data);

                createCategory(fileName);
            },
            error: function () {
                displayAlert(".message", "There was a problem when uploading the file!", "danger");
            }
        });
    } else {
        createCategory();
    }
};

When I run this code, I get the error

POST http://r3plica.localhost:3892/Api/Upload 415 (Unsupported Media Type)

but if I comment out the line contentType: false, and run my script I get a bad request, although my breakpoints get hit, the UploadModel is actually null.

Can anyone suggest a solution?

Cheers,

/r3plica

回答1:

Try adding dataType: 'json', if you think the service is returning JSON and replace the following error handeling function in your ajax call to get a better understanding of the type of problem you are facing

   error: function(xhr, exception) {
       if (xhr.status === 0) {
       alert('Not connected. Verify Login details or Network.');
       } else if (xhr.status == 401) {
       alert('Invalid Username or Password');
       } else if (xhr.status == 404) {
       alert('Requested page not found. [404]');
       } else if (xhr.status == 500) {
       alert('Internal Server Error [500].');
       } else if (exception === 'parsererror') {
       alert('Requested JSON parse failed.');
       } else if (exception === 'timeout') {
       alert('Time out error.');
       } else if (exception === 'abort') {
       alert('Ajax request aborted.');
       } else {
       alert('Uncaught Error.\n' + xhr.responseText);
       }
       }

comment out the content Type



回答2:

I had the same issue. In my case I had to add permissions for writing files. I followed this advice: https://stackoverflow.com/a/16948507/2549258 and my issue with 415 (Unsupported Media Type) disappeared.