fiberOptics
fiberOptics

Reputation: 7165

How to upload image from PhoneGap to Asp.Net Web API?

I have these available APIs:

[HttpPost]
[CorsEnabled]
[ActionName("upstream")]
public DTO.Callback UploadPhoto(Stream data)
{
    var m = new Logic.Components.User();
    return m.UploadPhoto(data, Common.UserValues().Email);
}

[HttpPost]
[CorsEnabled]
[ActionName("upbyte")]
public DTO.Callback UploadPhoto(byte[] data)
{
    var m = new Logic.Components.User();
    return m.UploadPhoto(data, Common.UserValues().Email);
}

[HttpPost]
[CorsEnabled]
[ActionName("upfile")]
public DTO.Callback UploadPhoto(HttpPostedFileBase data)
{
    var m = new Logic.Components.User();
    return m.UploadPhoto(data, Common.UserValues().Email);
}

[HttpPost]
[CorsEnabled]
[ActionName("up")]
public DTO.Callback UploadPhoto(DTO.UserPhoto data)
{
    var m = new Logic.Components.User();
    return m.UploadPhoto(data, Common.UserValues().Email);
}

UserPhoto class

public class UserPhoto
{
    public string Base64 { get; set; }
    public byte[] Data { get; set; }
}

In the behind code, I try to convert or get the equivalent byte[] of each request data.
If I would get the correct Image byte, then I'm good to go.

In my PhoneGap application, I have these codes:

A function that opens the camera:

takePicture: function (success, error) {
    var s = function (data) {
            navigator.camera.cleanup();
            (success || angular.noop)(data);
        },
        e = function (data) {
            navigator.camera.cleanup();
            (error || angular.noop)(data);
        };

    navigator.camera.getPicture(s, e,
        {
            quality: 100,
            destinationType: Camera.DestinationType.FILE_URI,
            sourceType: Camera.PictureSourceType.CAMERA,
            encodingType: Camera.EncodingType.PNG,
            correctOrientation: true
        }
    );
}

My first try is to convert the image to base64 string and use the 'up' API.
It works just fine for low quality not higher than 50. But the image becomes almost unrecognizable. So I set the quality to 100. And then the new problem comes, the phone hangs...

So I tried to use FileTransfer. Here is the code:

fileTransfer: function (filePath, serverUri, mimeType, params, success, error) {
    var
        u = $coreData.user.getSession()
        ;

    var options = new FileUploadOptions();
    options.fileKey = 'file';
    options.mimeType = mimeType;
    options.params = params;
    options.chunkedMode = true;
    options.headers = {
        Connection: 'close',
        Device: m.createDeviceHeader(),
        'Authentication-Token': (u && u.SessionKey),
        'Content-Type': 'application/json'
    };

    var ft = new FileTransfer();
    ft.upload(filePath, encodeURI(serverUri), success, error, options);
}

Sample usage:

uploadFile: function (path) {
    var def = $q.defer();
    $coreUtility
        .fileTransfer(path, $coreAPI.user.getUrl('upfile'), 'image/png', null,
        function (success) {


            def.resolve(m.callback(true, UPLOAD_PHOTO_SUCCESS, success));
        },
        function (error) {


            def.reject(m.callback(false, UPLOAD_PHOTO_FAIL, error));
        });
    return def.promise;
}  

But I was not able to upload the file, I always get not supported media type formatter and sometimes null reference exceptions. I'm totally out of idea.

Upvotes: 1

Views: 2968

Answers (1)

fiberOptics
fiberOptics

Reputation: 7165

Alright I get it now. For other struggling on the same problem, here is the solution.

    [HttpPost]
    [CorsEnabled]
    [ActionName("upfile")]
    public DTO.Callback UploadPhoto()
    {
        var m = new Logic.Components.User();
        return m.UploadPhoto(HttpContext.Current.Request, Common.UserValues().Email);
    }

Some logic:

    public DTO.Callback UploadPhoto(HttpRequest req, string email)
    {
        if (req.Files.Count > 0)
        {
            var file = req.Files[0];
            var m = new Logic.Components.User();
            return m.UploadPhoto(file.InputStream, email);
        }

        return new DTO.Callback { Message = "Fail to upload. Make sure that you are uploading an image file." };
    }  

Some explanation about the solution:

The first part is your API, and the second part is the backend code.

To pass the image stream from PhoneGap to your ASP.Net MVC Web API, you will just have to use HttpContext.Current.Request to get the Stream from Phonegap.

Upvotes: 2

Related Questions