iPhone: NSData и проблема байтового разговора? - PullRequest
0 голосов
/ 01 декабря 2011

Я хочу отправить изображение 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 в байт, но ASIHTTPRequest не позволяет устанавливать Data в качестве байтового типа данных:

    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"];

с использованием метода, указанного в this thread:

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

Ответы [ 2 ]

2 голосов
/ 02 декабря 2011

Это меня сильно раздражало!Мне просто нужно было заменить 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
}
0 голосов
/ 01 декабря 2011

Из перечисленной вами ошибки:

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

Я предполагаю, что вам нужно кодировать Base64 данные, идущие на ваш сервер.

Поэтому я бы рекомендовал использовать библиотеку Base64 для кодирования ваших данных.

И чтобы узнать, как это сделать, вот еще один вопрос, в котором есть детали реализации . Категория NSData, которую я использую в своем коде, содержится в ответе, автором которого является Алекс Рейнольдс.

...