Serenity: Upload file into varbinary column

Created on 28 Sep 2019  路  1Comment  路  Source: serenity-is/Serenity

Hello
I want to insert content of binary in FileUploadEditor to a table column(varbinary(MAX)).
AnyBody knows How to Insert Content of file to DB?

Most helpful comment

Create two columns:

  • YourFilePath VARCHAR(255)
  • YourFileBinary VARBINARY(MAX)

Add these fields to your xyzRow.cs:

[DisplayName("File"), Size(255)]
[FileUploadEditor(FilenameFormat = "SomePath/~", AllowNonImage = true, CopyToHistory = true)]
public String YourFilePath
{
    get { return Fields.YourFilePath[this]; }
    set { Fields.YourFilePath[this] = value; }
}

[DisplayName("File"), Size(-1), MinSelectLevel(SelectLevel.Details)]
public byte[] YourFileBinary
{
    get { return Fields.YourFileBinary[this]; }
    set { Fields.YourFileBinary[this] = value; }
}

Add this to your xyzForm.cs:

public String YourFilePath { get; set; }

Add this to your xyzRepository.cs:

private class MySaveHandler : SaveRequestHandler<MyRow> {
    protected override void BeforeSave()
    {
        base.BeforeSave();

        // This just turns the file into a byte array and saves that in the varbinary(max) column
        if (string.IsNullOrEmpty(Row.YourFilePath))
        {
            Row.YourFileBinary = new byte[] { };
        }
        else
        {
            // Only update the binary column if the file path has changed
            if (Row.YourFilePath != Old.YourFilePath)
            {
                var fileName = UploadHelper.DbFilePath(Row.YourFilePath);
                FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
                BinaryReader br = new BinaryReader(fs);
                byte[] bytes = br.ReadBytes((int)fs.Length);
                br.Close();
                fs.Close();
                Row.YourFileBinary = bytes;
            }
        }
    }
}

I haven't needed to download these files, so if you need to download them you will want to try create some download endpoint in your xyzEndpoint.cs:

[HttpPost]
public ActionResult ExportFile(IDbConnection connection, RetrieveRequest request)
{
    RetrieveResponse<MyRow> Response = new MyRepository().Retrieve(connection, request);
    byte[] fileContent = Response.Entity.YourFileBinary;
    var output = File(fileContent, System.Net.Mime.MediaTypeNames.Application.Octet, "FileName.xyz");
    return output;
}

and then add this to your xyzGrid.ts:

protected getColumns() {
    var columns = super.getColumns();

    columns.splice(1, 0, {
        field: 'Download File',
        name: '',
        format: ctx => '<a class="inline-action download-file" title="Download">' +
            '<i class="fa fa-file-text-o text-blue"></i></a>',
        width: 24,
        minWidth: 24,
        maxWidth: 24
    });

    return columns;
}


protected onClick(e: JQueryEventObject, row: number, cell: number) {
    super.onClick(e, row, cell);

    if (e.isDefaultPrevented())
        return;

    var item = this.itemAt(row);
    var target = $(e.target);

    // if user clicks "i" element, e.g. icon
    if (target.parent().hasClass('inline-action'))
        target = target.parent();

    if (target.hasClass('inline-action')) {
        e.preventDefault();

        if (target.hasClass('download-file')) {
            let ServiceEndpoint = this.getService() + "/ExportFile";
            Q.postToService({ service: ServiceEndpoint, request: { EntityId: item.FileId }, target: '_blank' });
        }
    }
}

>All comments

Create two columns:

  • YourFilePath VARCHAR(255)
  • YourFileBinary VARBINARY(MAX)

Add these fields to your xyzRow.cs:

[DisplayName("File"), Size(255)]
[FileUploadEditor(FilenameFormat = "SomePath/~", AllowNonImage = true, CopyToHistory = true)]
public String YourFilePath
{
    get { return Fields.YourFilePath[this]; }
    set { Fields.YourFilePath[this] = value; }
}

[DisplayName("File"), Size(-1), MinSelectLevel(SelectLevel.Details)]
public byte[] YourFileBinary
{
    get { return Fields.YourFileBinary[this]; }
    set { Fields.YourFileBinary[this] = value; }
}

Add this to your xyzForm.cs:

public String YourFilePath { get; set; }

Add this to your xyzRepository.cs:

private class MySaveHandler : SaveRequestHandler<MyRow> {
    protected override void BeforeSave()
    {
        base.BeforeSave();

        // This just turns the file into a byte array and saves that in the varbinary(max) column
        if (string.IsNullOrEmpty(Row.YourFilePath))
        {
            Row.YourFileBinary = new byte[] { };
        }
        else
        {
            // Only update the binary column if the file path has changed
            if (Row.YourFilePath != Old.YourFilePath)
            {
                var fileName = UploadHelper.DbFilePath(Row.YourFilePath);
                FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
                BinaryReader br = new BinaryReader(fs);
                byte[] bytes = br.ReadBytes((int)fs.Length);
                br.Close();
                fs.Close();
                Row.YourFileBinary = bytes;
            }
        }
    }
}

I haven't needed to download these files, so if you need to download them you will want to try create some download endpoint in your xyzEndpoint.cs:

[HttpPost]
public ActionResult ExportFile(IDbConnection connection, RetrieveRequest request)
{
    RetrieveResponse<MyRow> Response = new MyRepository().Retrieve(connection, request);
    byte[] fileContent = Response.Entity.YourFileBinary;
    var output = File(fileContent, System.Net.Mime.MediaTypeNames.Application.Octet, "FileName.xyz");
    return output;
}

and then add this to your xyzGrid.ts:

protected getColumns() {
    var columns = super.getColumns();

    columns.splice(1, 0, {
        field: 'Download File',
        name: '',
        format: ctx => '<a class="inline-action download-file" title="Download">' +
            '<i class="fa fa-file-text-o text-blue"></i></a>',
        width: 24,
        minWidth: 24,
        maxWidth: 24
    });

    return columns;
}


protected onClick(e: JQueryEventObject, row: number, cell: number) {
    super.onClick(e, row, cell);

    if (e.isDefaultPrevented())
        return;

    var item = this.itemAt(row);
    var target = $(e.target);

    // if user clicks "i" element, e.g. icon
    if (target.parent().hasClass('inline-action'))
        target = target.parent();

    if (target.hasClass('inline-action')) {
        e.preventDefault();

        if (target.hasClass('download-file')) {
            let ServiceEndpoint = this.getService() + "/ExportFile";
            Q.postToService({ service: ServiceEndpoint, request: { EntityId: item.FileId }, target: '_blank' });
        }
    }
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

stepankurdylo picture stepankurdylo  路  3Comments

ahsansolution picture ahsansolution  路  3Comments

kilroyFR picture kilroyFR  路  3Comments

newyearsoft picture newyearsoft  路  3Comments

StefanTheiner picture StefanTheiner  路  3Comments