iPhone: Проблем с NSData и байтов разговор?

Искам да изпратя изображение на iPhone към сървърна база данни. Написах следния код. Получавам изключение за несъответствие на данни и не мога да го разреша. Може ли някой да ми помогне.

Код от страната на iPhone:

- (void) uploadUserInfo:(NSString*)userId profilePic:(UIImage*)profilePic {

    __block ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL: [NSURL URLWithString:[NSString stringWithFormat:@"%@/%d/uploadUserInfo?cultureDetect=false", dataUrl, currentAppID]]];

    [request setPostValue:userId forKey: @"userId"];
    // Upload an image
    [request addPostValue:@"pic.jpg" forKey:@"fileName"];
    NSData* imageData = UIImageJPEGRepresentation(profilePic, 1);
    [request setData:imageData withFileName:@"pic.jpg" andContentType:@"image/jpeg" forKey:@"profilePic"];

    [request setDelegate:self];
    [request setDidFinishSelector:@selector(uploadRequestFinished:)];
    [request setDidFailSelector:@selector(uploadRequestFailed:)];

    [queue addOperation: request];
    [queue go];

}

Код на ASP.NET MVC уебсайт Контролер:

    public void uploadUserInfo(string userId, string fileName, byte[] profilePic)
    {
        int ID;
        if (int.TryParse(appId, out ID) && fileName != null && profilePic != null)
        {
            Image model = new Image();
            System.Drawing.Image image = System.Drawing.Image.FromStream(new System.IO.MemoryStream(profilePic));
            System.Drawing.Point maxSize = FileUtils.GetImageMaxSize(Image.ImageTypeEnum.TableCellImage);
            System.Drawing.Image thumb = ImageUtilities.GetFixedSizeImage(image, InterpolationMode.HighQualityBicubic, null, PixelFormat.Format32bppArgb, maxSize.X, maxSize.Y, false);
            byte[] resizedContent = ImageUtilities.GetBytesFromImage(thumb, ImageFormat.Png);
            model.AmendedDateTime = DateTime.Now;
            model.ApplicationId = ID;
            model.ImageType = Image.ImageTypeEnum.TableCellImage;
            string contentType = ImageUtilities.GetContentType(resizedContent);

            FileInfo f = new FileInfo(fileName);
            string name = f.Name.Substring(0, f.Name.Length - f.Extension.Length);
            string extension = f.Extension.Substring(1);

            BinaryFile file = new BinaryFile()
            {
                ContentType = contentType,
                FileName = name,
                FileExtension = extension
            };

            file.Data = resizedContent;
            model.BinaryFile = file;

            this.DataContext.Images.Table.InsertOnSubmit(model);

            ValidateAndSubmitChanges();
        }
        return;
    }

Получавам следната грешка, преди моят метод да започне да се изпълнява. т.е. предполагам, че MVC двигателят хвърля изключение директно, когато типът на данните не съвпада.

 [FormatException]: The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or a non-white space character among the padding characters. 
   at System.Convert.FromBase64String(String s)
   at System.Web.Mvc.ByteArrayModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
   at System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor)
   at System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
   at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
   at System.Web.Mvc.Controller.ExecuteCore()
   at System.Web.Mvc.MvcHandler.<>c__DisplayClass8.<BeginProcessRequest>b__4()
   at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.<MakeVoidDelegate>b__0()
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Опитах се да конвертирам NSData в Byte, но ASIHTTPRequest не позволява да се зададе Data като тип данни Byte:

    NSUInteger len = [imageData length];
    Byte *byteData = (Byte*)malloc(len);
    memcpy(byteData, [imageData bytes], len);
    [request setData:byteData withFileName:@"pic.jpg" andContentType:@"image/jpeg" forKey:@"profilePic"];

Преобразуването в Base64 дава същото изключение!

използвайки вграден статичен метод ASIHTTPRequest:

  NSData* imageData = UIImageJPEGRepresentation(profilePic, 1);
  [request setData:[ASIHTTPRequest base64forData:imageData] withFileName:@"pic.jpg" andContentType:@"image/jpeg" forKey:@"profilePic"];

използвайки метода, даден в тази тема:

    NSData* imageData = UIImageJPEGRepresentation(profilePic, 1);
    [request setData:[NSString base64StringFromData:imageData length:[imageData length]]  withFileName:@"pic.jpg" andContentType:@"image/jpeg" forKey:@"profilePic"];

person AlienMonkeyCoder    schedule 01.12.2011    source източник


Отговори (2)


Това много ме подразни! Просто трябваше да заменя Byte[] с HttpPostedFileBase, който автоматично обработва публикуваните файлове.

Код на iPhone:

    - (void) uploadUserInfo:(NSString*)userId profilePic:(UIImage*)profilePic {

    __block ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL: [NSURL URLWithString:[NSString stringWithFormat:@"%@/app/%d/phone/uploadUserInfo?cultureDetect=false", dataUrl, currentAppID]]];

    NSData* imageData = UIImageJPEGRepresentation(profilePic, 1);
    [request setData:imageData  withFileName:@"pic.jpg" andContentType:@"image/jpeg" forKey:@"imageFile"];

    [request setDelegate:self];
    [request setDidFinishSelector:@selector(uploadRequestFinished:)];
    [request setDidFailSelector:@selector(uploadRequestFailed:)];

    [queue addOperation: request];
    [queue go];
}

Код на ASP.NET MVC контролер:

public void uploadUserInfo(HttpPostedFileBase imageFile)
{
       // Process imageFile
}
person AlienMonkeyCoder    schedule 02.12.2011

От изброената от вас грешка:

[FormatException]: The input is not a valid Base-64 string as it contains a non-base 64 character...

Предполагам, че трябва да кодирате Base64 данните, отиващи до вашия сървър.

Така че бих препоръчал да използвате библиотека Base64 за кодиране на вашите данни.

И за да разберете как да направите това, ето още един въпрос, който съдържа подробности за внедряването. Категорията NSData, която използвам в собствения си код, е в отговора, автор на Алекс Рейнолдс.

person Michael Dautermann    schedule 01.12.2011
comment
Здравей Майкъл, благодаря за информацията. Вече минах през връзката, която ми изпратихте. Опитах се да използвам [ASIHTTPRequest base64forData:imageData] статичен метод, както е редактиран в първоначалния ми въпрос, но дава същото изключение! Освен това, ако премахна изпращането на данни за изображения, тогава всичко останало работи перфектно! Така че трябва да има нещо общо с NSData на goal-c и byte на ASP.NET MVC! Не знам какво става. - person AlienMonkeyCoder; 01.12.2011
comment
Току-що се опитах да използвам тези категории, създадени от Алекс Рейнолдс, но същото изключение! Редактира въпроса. - person AlienMonkeyCoder; 01.12.2011