I have a socket communication based application and the server sends a request to a client for a signature image. The signature is taken at the client and sent back to the server.
To do this I have used a picture box, who's data is converted into bytes and then into a string to send over the socket connection to the server. This all works OK.
I am having problems saving the data received in the database because I need to be able to save it as an image type but at this point the data is still a string so I am getting the error:
"Operand type clash: nvarchar is incompatible with image"
I presume it's because I am trying to send a string to a sql image type?
Code which attempts to call the procedure and errors (server end- received data as string):
try
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["GetConnector"].ConnectionString))
{
SqlCommand sqlComm = new SqlCommand("PL_Device_ReadData", conn);
sqlComm.Parameters.AddWithValue("@DeviceTypeID", DeviceID);
sqlComm.Parameters.AddWithValue("@RequestID", RequestID);
if (DeviceID != "5")
{
sqlComm.Parameters.AddWithValue("@Reading", Reading);
}
else if (DeviceID == "5")
{
sqlComm.Parameters.AddWithValue("@ImageReading", Reading);
sqlComm.Parameters.Add("@ImageReading", SqlDbType.Image);
sqlComm.Parameters["@ImageReading"].Value = Reading;
}
sqlComm.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = sqlComm;
da.Fill(ds);
}
}
catch (Exception e)
{
}
Stored Procedure:
ALTER PROCEDURE [dbo].[PL_Device_ReadData]
@DeviceTypeID INT,
@RequestID INT,
@Reading NVARCHAR(100) = NULL,
@ImageReading IMAGE = NULL
AS
BEGIN
--Data
IF @DeviceTypeID = 5
BEGIN
UPDATE dbo.DeviceRequests
SET ImageData = @ImageReading
WHERE id = @RequestID
AND DeviceTypeID = @DeviceTypeID
END
ELSE
BEGIN
UPDATE dbo.DeviceRequests
SET Value = @Reading
WHERE id = @RequestID
AND DeviceTypeID = @DeviceTypeID
END
END
Converting the image into bytes:
byte[] imgData = null;
// storage for the img bytes
imgData = ImgToByteArray(picSignature.InitialImage, ImageFormat.Jpeg);
public static byte[] ImgToByteArray(Image img, ImageFormat imgFormat)
{
byte[] tmpData = null;
using (MemoryStream ms = new MemoryStream())
{
img.Save(ms, imgFormat);
tmpData = ms.ToArray();
}
// dispose of memstream
return tmpData;
}
Converting the bytes to string (to send over socket):
_Reading = System.Text.Encoding.UTF8.GetString(_imagevalues);
To do this I have used a picture box, who's data is converted into bytes and then into a string to send over the socket connection to the server. This all works OK.
Given the code you've shown, I'd suggest it probably doesn't. In particular:
_Reading = System.Text.Encoding.UTF8.GetString(_imagevalues);
Image data is not UTF-8-encoded text, so you shouldn't be using Encoding.UTF8
or indeed any encoding. Encodings are designed to convert natural plain text into bytes and back. Instead, you have arbitrary binary data.
Ideally, you should transmit this over the socket as binary data - it's not clear why you need a string at all. If you really do need a string though, you should convert the bytes into text using base64:
string base64 = Convert.ToBase64String(bytes);
then on the other side, you can do the reverse:
byte[] bytes = Convert.FromBase64String(base64);
But as I say, if you're in control of the protocol, it would be cleaner and more efficient to just transmit the bytes in binary form without converting them to text at all. We can't tell what protocol this is, so it's hard to know whether or not that's an option.
See more on this question at Stackoverflow