0

I want to download file, that was earlier but into database as byte[] (varbinary(max) in sql), but when I try to call DownloadCv method I get exception: "Input Data is not valid base-64 string."

Could You help me find my mistake or show another way to download file please? Cheers.

Here is what I currently have:

public class ApplyForm
{
    /*Some other properties
        ...
    */
    public int FileSize { get; set; }
    public string FileName { get; set; }
    public byte[] FileData { get; set; }
    public string ContentType { get; set; }
}

//Apply View

@model SourceTreeITMatchmaking.Core.Model.ApplyForm

@{
    ViewBag.Title = "Apply";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

    <div>
        <!-- Some properties to bind to ApplyForm are not shown here to avoid misunderstandings-->
        <input class="form-control col-md-2" type="file" name="file" />
        <input class="form-control col-md-2" type="submit" value="Upload" />
        <input type="hidden" name="jobOfferId" value="@Model.TargetOfferId" />
    </div>

//Apply action after posting form

[HttpPost]
public ActionResult Apply(HttpPostedFileBase file, ApplyForm applyForm, int jobOfferId)
{
    if (file.ContentLength > 0)
    {
        applyForm.FileName = file.FileName;
        applyForm.FileSize = file.ContentLength;
        applyForm.FileData = GetFileBytes(file);
        applyForm.ContentType = file.ContentType;

        dbConnection.ApplyForms.Add(applyForm);
        dbConnection.SaveChanges();

        return RedirectToAction("JobList", "JobOffer");
    }
}

//Method to get byte[] from HttpPostedFileBase

private static byte[] GetFileBytes(HttpPostedFileBase file)
{
    var streamLength = file.InputStream.Length;
    var imageBytes = new byte[streamLength];

    file.InputStream.Read(imageBytes, 0, imageBytes.Length);
    return imageBytes;
}   

//MyOffersController

public ActionResult JobOfferReplies(int jobOfferId)
{
    List<ApplyForm> allReplies = dbConnection.ApplyForms.Where(x => x.TargetOfferId == jobOfferId).ToList();

    return View(allReplies);
}

//JobOfferReplies View

@model List<SourceTreeITMatchmaking.Core.Model.ApplyForm>

@{
    ViewBag.Title = "JobOfferReplies";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<div>
     @Html.ActionLink("Download CV", "DownloadCv", "MyOffers", new {file = applyForm.FileData, contentType = applyForm.ContentType }, new { @class = "btn btn-default pull-left" })
<div>

//MyOffersController

public FileContentResult DownloadCv(byte[] file, string contentType)
{
    return new FileContentResult(file, contentType);
}
7
  • Please show the full stack trace of the exception Commented Dec 3, 2015 at 11:06
  • Full error message: 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 Commented Dec 3, 2015 at 14:49
  • Stack trace: System.Convert.FromBase64_Decode(Char* startInputPtr, Int32 inputLength, Byte* startDestPtr, Int32 destLength) +11961555 System.Convert.FromBase64CharPtr(Char* inputPtr, Int32 inputLength) +130 System.Convert.FromBase64String(String s) +42 System.Web.Mvc.ByteArrayModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +98 Castle.Proxies.Invocations.IModelBinder_BindModel.InvokeMethodOnTarget() +118 Castle.DynamicProxy.AbstractInvocation.Proceed() +80 Commented Dec 3, 2015 at 14:49
  • Seems like there is some problem when I want transfer applyForm.FileData from View to Controller in this line: @Html.ActionLink("Download CV", "DownloadCv", "MyOffers", new {file = applyForm.FileData, contentType = applyForm.ContentType }, new { @class = "btn btn-default pull-left" }) Because in DownloadCV method I get null for file byte[] but contentType is ok. Commented Dec 3, 2015 at 15:02
  • 1
    Okay, nevermind I solved it :) Im now passing only Id, not whole byte[] :) And then in controller I just search database for specified ID. Sorry for bothering You :) Cheers. Commented Dec 3, 2015 at 15:35

1 Answer 1

2

In our code we do it as follows:

entityItem= new byte[file.ContentLength];
file.InputStream.Read(entityItem, 0, file.ContentLength);
file.InputStream.Close();

And to return

return File(entityItem, "application/octet-stream");
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.