Reyhan M.T Ответов: 1

Почему я не могу отправить base64 sting в свою базу данных SQL


У меня возникла проблема, когда я выбираю картинку размером 500 Кб из своей галереи и мое приложение принудительно закрывается. Но если я выберу картинку размером 100-499kb, то это будет успешная загрузка изображения и отправка base64 в мою базу данных. Не могли бы вы помочь мне, как это исправить ?

Что я уже пробовал:

Это мое кодирование из мобильного приложения:
async void SavePicture(object sender, EventArgs e)
 {
        file = await CrossMedia.Current.PickPhotoAsync(new PickMediaOptions
        {
            PhotoSize = PhotoSize.Small
            //CompressionQuality = 100,

        });

        if (file == null)
            return;


        //Convert image to string
        FileStream fs = new FileStream(file.Path, FileMode.Open, FileAccess.Read);
        byte[] ImageData = new byte[fs.Length];
        fs.Read(ImageData, 0, System.Convert.ToInt32(fs.Length));
        fs.Close();
        string imgResized = Convert.ToBase64String(ImageData);

        imageResize.Source = file.Path;

        api = RestService.For<ApiInterface> 
        ("http://192.168.0.190/webservice/webservice.asmx");

        String idgoogle = "";

        var id = Application.Current.Properties["Id"].ToString();

        var stringimage = imgResized;


        User user = new User(idgoogle);
        user.Profile_Image = stringimage;
        user.Id = id;


        var responseupdate = await api.UpdateGoogle(new UpdateGoogleQuery(user));

        if (responseupdate.isSuccess)
        {
            Loading.toast("Sukses Menyimpan Foto");
        }
        else
        {
            LoadingFailed.toast("Gagal Menyimpan Foto");
        }

}

Это мое кодирование от webservice:
public void update(User dtGoogle)
{
        String sql = $"UPDATE google SET profile_image = ('{dtGoogle.Profile_Image}') WHERE id = ('{dtGoogle.Id}')";
        Connection.executeSql(sql);
}



[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public void UpdateGoogle(String jsonOfData)
{
   Tools.Log("Check Update Google First", "AppDebugGoogle.txt");
   DbAccessConnection conn = getActiveConnection();

   if (conn == null)
     return;

   try
   {
      beginTransaction(conn);

      Google google = new Google(conn);
      Tools.Log("Check Update Google Second", "AppDebugGoogle.txt");
      User users = Tools.convertJsonIncludeDerivedTypes<User>(jsonOfData);
      Tools.Log("Check Update Google Third", "AppDebugGoogle.txt");

      google.update(users);
      Tools.Log("Check Update Google Four", "AppDebugGoogle.txt");

      commitTransaction(conn);
      Tools.Log("Check Update Google Five", "AppDebugGoogle.txt");
      Responder.writeResponse(true, "Success Update Data User Google");
    }
      catch (Exception ex)
      {
        Tools.Log("Check Update Google Six", "AppDebugGoogle.txt");
        rollbackTransaction(conn);
        Responder.writeResponse(false, ex.Message, ex.StackTrace);
       }
    }


Это сообщение об ошибке, когда я выбираю картинку с 500 кб с моего телефона:
Refit.ApiException: 'Response status code does not indicate success: 500 (Internal Server Error).'

Я пытаюсь использовать запись журнала в методе UpdateGoogle в веб-сервисе это успех создания AppDebugGoogle.txt и распечатайте запись журнала, когда я выберу картинку размером 100-499 кб с моего телефона. Но если я выберу картинку размером 500 КБ со своего телефона и проверю AppDebugGoogle.txt это не печатная запись в журнале.

Richard MacCutchan

Почему вы преобразуете его в строку Base64? Просто сохраните данные в виде простого массива байтов. Это также сэкономит вам всю дополнительную память при преобразовании изображения в строку.

OriginalGriff

Это может быть сделано для экономии времени обработки на выходе: нет необходимости преобразовывать его в строку base64 каждый раз, когда вы отображаете / вставляете изображение. При стоимости хранения и "относительно небольшом" размере файла не является большой проблемой хранить 750 КБ вместо необработанных 500 КБ. Неэффективно, но если это небольшое количество изображений, которые используются часто ...

Но, вероятно, это потому, что он не знает, как сохранить нетекстовые данные.

Richard MacCutchan

Да, и, вероятно, по той же причине, что и он. System.Convert.ToInt32(fs.Length).

OriginalGriff

Это, вероятно, потому, что это long и компилятор жаловался на отсутствие метода сопоставления ... Я не могу потрудиться научить его сегодня кастингу ... :вздох:

1 Ответов

Рейтинг:
1

OriginalGriff

Просто: вы делаете это очень, очень опасным способом.
Никогда не объединяйте строки для построения команды SQL. Это оставляет вас широко открытыми для случайной или преднамеренной атаки SQL-инъекции, которая может уничтожить всю вашу базу данных. Вместо этого всегда используйте параметризованные запросы.

Когда вы объединяете строки, вы вызываете проблемы, потому что SQL получает такие команды, как:

SELECT * FROM MyTable WHERE StreetAddress = 'Baker's Wood'
Цитата, добавленная пользователем, завершает строку в том, что касается SQL, и вы получаете проблемы. Но могло быть и хуже. Если я приду и наберу вместо этого: "x';DROP TABLE MyTable;--", то SQL получит совсем другую команду:
SELECT * FROM MyTable WHERE StreetAddress = 'x';DROP TABLE MyTable;--'
Которые SQL видит как три отдельные команды:
SELECT * FROM MyTable WHERE StreetAddress = 'x';
Совершенно правильный выбор
DROP TABLE MyTable;
Вполне допустимая команда "удалить таблицу"
--'
А все остальное-это комментарии.
Так оно и происходит: выбирает любые совпадающие строки, удаляет таблицу из базы данных и игнорирует все остальное.

Поэтому всегда используйте параметризованные запросы! Или будьте готовы часто восстанавливать свою БД из резервной копии. Вы ведь регулярно делаете резервные копии, не так ли?

Исправьте это во всем вашем приложении - включая приведенный выше код - и проблема, которую вы заметили здесь, также исчезнет: SQL имеет максимальную длину текста команды 64K * размер сетевого пакета (он меньше в более ранних версиях), а строки Base64 на 4/3 длиннее вводимых вами данных ...


Reyhan M.T

да, я перепишу свой код в void update. Большое вам спасибо,я использую средний текст в поле profile_image в таблице google. Но если я использую команду drop in public void Update то она удалит таблицу google в моей базе данных sql

Christian Graus

ЭТО ЕГО ТОЧКА ЗРЕНИЯ!!! Инъекция позволяет кому-то удалить ваши таблицы

jsc42

Также проверьте размер поля в базе данных, в которую сохраняются данные. Большое изображение потребует большого объема памяти, и (как уже упоминалось) преобразование в Base64 увеличивает размер на 1/3. Если результирующий размер больше максимального размера, который может содержать поле, то обновление базы данных завершится неудачей.500Kb потребуется поле, которое может содержать 682668 байт.

OriginalGriff

В два раза больше, если поле объявлено как Unicode (NVARCHAR вместо VARCHAR), поскольку оно выделяет пару байтов на символ.