由于Base64错误,无法将Image上传到数据库

时间:2017-01-15 21:13:01

标签: c# asp.net sql-server wcf model-view-controller

我正在学习如何将图像上传到数据库然后检索它的教程。我的WCF服务工作正常,它有一个将数据插入数据库的功能,如下所示:

public bool CreateTeam(string userId, string teamId, string name, string coach, byte[] photo)
    {
        string query = "INSERT INTO t" + userId + "(Id, Name, Coach, Photo) VALUES (@id, @name, @coach, @photo)";

        try
        {
            SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["TeamsConnectionString"].ConnectionString);
            SqlCommand command = new SqlCommand(query, connection);

            connection.Open();
            command.Parameters.AddWithValue("@id", teamId);
            command.Parameters.AddWithValue("@name", name);
            command.Parameters.AddWithValue("@coach", coach);
            command.Parameters.AddWithValue("@photo", photo);
            command.ExecuteNonQuery();
            connection.Close();

            return true;
        }

        catch (Exception ex)
        {
            Console.WriteLine("" + ex.Message);

            return false;
        }
    }

在我的控制器中,我引用了WCF服务和HttpPostedFileBase来获取上传的文件,如下所示:

[HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(Team team)
    {
        if (ModelState.IsValid)
        {
            HttpPostedFileBase photo = Request.Files["Photo"];

            TeamsService.ServiceClient client = new TeamsService.ServiceClient();
            client.Open();

            if (client.CreateTeam(Session["DynamixSessionId"].ToString(), team.Id, team.Name, team.Coach, ConvertToBytes(photo)))
            {
                client.Close();

                return RedirectToAction("Index", "Teams");
            }

            else
            {
                return View();
            }
        }

        return View();
    }

ConvertToBytes功能概述如下:

public byte[] ConvertToBytes(HttpPostedFileBase file)
    {
        byte[] fileBytes = null;

        BinaryReader reader = new BinaryReader(file.InputStream);
        fileBytes = reader.ReadBytes((int)file.ContentLength);

        return fileBytes;
    }

我的Team模型如此:

[Key]
    [Required(AllowEmptyStrings = false, ErrorMessage = "This cannot be empty")]
    public string Id { get; set; }

    [Required(AllowEmptyStrings = false, ErrorMessage = "This cannot be empty")]
    public string Name { get; set; }

    [Required(AllowEmptyStrings = false, ErrorMessage = "This cannot be empty")]
    public string Coach { get; set; }

    public byte[] Photo { get; set; }

    public HttpPostedFileBase File { get; set; }

在我的视图中,我有一个enctype属性的表单,如下所示:

@using (Html.BeginForm("Create", "Teams", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.AntiForgeryToken() 
        <div class="form-horizontal">
                @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                <div class="form-group">
                    @Html.LabelFor(model => model.Id, htmlAttributes: new { @class = "control-label col-md-2" })
                    <div class="col-md-10">
                        @Html.EditorFor(model => model.Id, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.Id, "", new { @class = "text-danger" })
                    </div>
                </div>

                <div class="form-group">
                    @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
                    <div class="col-md-10">
                        @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
                    </div>
                </div>

                <div class="form-group">
                    @Html.LabelFor(model => model.Coach, htmlAttributes: new { @class = "control-label col-md-2" })
                    <div class="col-md-10">
                        @Html.EditorFor(model => model.Coach, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.Coach, "", new { @class = "text-danger" })
                    </div>
                </div>

                <div class="form-group">
                    <input type="file" name="Photo" id="Photo" />
                </div>
            </div>
}

当我单击提交按钮时,其他字段正确插入,我可以从我的SQL Server数据库中看到它们。只要我添加Photo字段(类型为varbinary),就会出现以下错误:

  

输入不是有效的Base-64字符串,因为它包含非基本64个字符,两个以上的填充字符或填充字符中的非法字符。

为什么我收到此错误?有关如何解决错误的任何建议吗?

2 个答案:

答案 0 :(得分:2)

我的建议是你应该指定参数类型。 commandd.Parameters.Add("@photo", SqlDbType.VarBinary, LengthOfFieldOnTheServerSide).Value = photo;此建议基于我之前与SQL查询的“斗争”。对我来说,它是在system.byte []的参数位置创建查询,而不是byte []的实际值。

抱歉打字错误我正在手机上使用StackExchange应用

答案 1 :(得分:2)

为什么使用模型中Photo字段的ID来控制文件上传? Photo字段必须是HttpPostedFileBase类型,才能正确上传图片并避免Base64错误。我建议你做出以下改变:

  1. 模型中,添加以下内容:

    public HttpPostedFileBase UploadedPhoto { get; set; }
    
  2. 视图中,添加以下内容:

    <input type="file" name="UploadedPhoto" id="UploadedPhoto" />
    
  3. 控制器中,添加以下内容:

    HttpPostedFileBase photo = Request.Files["UploadedPhoto"];
    
    TeamsService.ServiceClient client = new TeamsService.ServiceClient();
    client.Open();
    
    if (client.CreateTeam(Session["DynamixSessionId"].ToString(), team.Id, team.Name, team.Coach, ConvertToBytes(photo)))
    {
        client.Close();
    
        return RedirectToAction("Index", "Teams");
    }
    
    else
    {
        return View();
    }
    
  4. 这应该可以解决你的问题。