OGeek|极客世界-中国程序员成长平台

标题: ios - ASP.NET 存储过程调用将 VarBinary 插入 sql [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-12 14:39
标题: ios - ASP.NET 存储过程调用将 VarBinary 插入 sql

我有一个字符串,它是来自 iOS 的数据字节 base64EncodedString,它是一个非常长的字符串

let imageStr = imageData.base64EncodedString()

我正在从我的 ios 调用一个 .NET 方法,该方法将调用一个存储过程将这些字节插入数据库。

这是我的 .NET 方法,我将数据类型设置为 VarBinary

public string PostLandGradingImages(List<Images> landingCells)
{
    try
    {
        using (connection = new SqlConnection(connectionString))
        {
            connection.Open();

            using (SqlCommand command = new SqlCommand("ostLandGradingImages", connection))
            {
                command.CommandType = CommandType.StoredProcedure;

                for (int i = 0; i < landingCells.Count; i++)
                {
                    command.Parameters.Clear();

                    SqlParameter parameter1 = new SqlParameter("@Job_No", SqlDbType.VarChar);
                    parameter1.Value = landingCells[i].jobNo;
                    parameter1.Direction = ParameterDirection.Input;
                    command.Parameters.Add(parameter1);

                    SqlParameter parameter2 = new SqlParameter("@Image", SqlDbType.VarBinary);
                    parameter2.Value = landingCells[i].imageBytes;
                    parameter2.Direction = ParameterDirection.Input;
                    command.Parameters.Add(parameter2);

                    command.ExecuteNonQuery();
                }
            }
        }
    }
    catch (Exception e)
    {
        return e.Message.ToString();
    }

    return "All Good";
}

这是我的图像类,注意我的 imageBytes 被定义为一个字节[]:

public class Images
{
    public string jobNo { get; set; }
    public byte[] imageBytes { get; set; }
}

我要插入的列定义为 varbinary(MAX)

这是我的存储过程:

ALTER PROCEDURE [dbo].[PostLandGradingImages] 
    -- Add the parameters for the stored procedure here
    @Job_No varchar(MAX) = NULL,
    @Image varbinary(MAX) = NULL
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here
    INSERT INTO LandGradingImages (Job_No, ImageBytes) VALUES (@Job_No, @Image)
END

我的问题是没有插入任何内容,我的捕获中出现此错误:

Object reference not set to an instance of an object.

我的问题是,我做错了什么?我不应该发送 base64EncodedString 还是我没有正确设置我的类(class)?还是我的数据库专栏?

我试过了:

byte[] bytes = System.Convert.FromBase64String(landingCells[i].imageBytes);

SqlParameter parameter2 = new SqlParameter("@Image", SqlDbType.VarBinary, 800000);
parameter2.Value = bytes;
parameter2.Direction = ParameterDirection.Input;
command.Parameters.Add(parameter2);

仍然不起作用我将 imageBytes 更改为字符串。



Best Answer-推荐答案


我将您的代码修改为以下方法。它为每个 Image 创建一个新的 CommandType.StoredProcedure。每个图像也会返回结果,因此您可以查看哪些失败了。在你的方法中,如果你有 10 张图像,而第 9 张失败了,你就不会知道。

public List<Images> PostLandGradingImages(List<Images> landingCells)
{
    //create a connection to the database
    using (SqlConnection connection = new SqlConnection(Common.connectionString))
    {
        //loop all the images
        for (int i = 0; i < landingCells.Count; i++)
        {
            //create a fresh sql command for every Image
            using (SqlCommand command = new SqlCommand("ostLandGradingImages", connection))
            {
                command.CommandType = CommandType.StoredProcedure;

                //add the parameters
                command.Parameters.Add("@Job_No", SqlDbType.VarChar).Value = landingCells[i].jobNo;
                command.Parameters.Add("@Image", SqlDbType.VarBinary).Value = landingCells[i].imageBytes;

                try
                {
                    //open the connection if closed
                    if (connection.State == ConnectionState.Closed)
                    {
                        connection.Open();
                    }

                    //execute the stored procedure
                    command.ExecuteNonQuery();

                    //set the save result to the image
                    landingCells[i].saveResult = true;
                }
                catch (Exception ex)
                {
                    //handle error per Image
                    landingCells[i].errorMessage = ex.Message;
                }
            }
        }
    }

    return landingCells;
}

为了跟踪每个图像的保存结果,我向 Image 类添加了两个属性,但这也可以通过其他各种方式完成。

public class Images
{
    public string jobNo { get; set; }
    public byte[] imageBytes { get; set; }

    public bool saveResult { get; set; }
    public string errorMessage { get; set; }
}

使用以下代码完成了一个简单的测试。他们都没有给出 NullReference 错误。即使两个属性都为 null,仍然会创建一个数据库条目。

//create a new list with Images
List<Images> landingCells = new List<Images>();

//add some dummy data
landingCells.Add(new Images() { jobNo = null, imageBytes = null });
landingCells.Add(new Images() { jobNo = "Job 1", imageBytes = null });
landingCells.Add(new Images() { jobNo = null, imageBytes = new byte[10000] });
landingCells.Add(new Images() { jobNo = "Job 2", imageBytes = new byte[10000] });

//send the images to be saved
landingCells = PostLandGradingImages(landingCells);

//loop all the images to check the result
for (int i = 0; i < landingCells.Count; i++)
{
    if (landingCells[i].saveResult == false)
    {
        //display the result for each failed image
        Label1.Text += landingCells[i].errorMessage + "<br>";
    }
}

如果仍然有 NullReference 错误,这意味着您的 List landingCells 本身为 null,或者该 List 中的 Image 对象为 null(在这种情况下,它不应该被添加到 List首先恕我直言)。您可以轻松更改代码段以进行检查。

关于ios - ASP.NET 存储过程调用将 VarBinary 插入 sql,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50176982/






欢迎光临 OGeek|极客世界-中国程序员成长平台 (http://ogeek.cn/) Powered by Discuz! X3.4