November Happy Hour will be moved to Thursday December 5th.

Intercept private NormalizeData of EPiServer.Forms CSVDataExporter

Vote:
 

Hi all,

what would be the correct way to intercept NormalizeData method (which is private) of CSVDataExporter class to add additional normalization, without creating additional option for form submissions export ("Exaport as...")?

#201065
Edited, Feb 04, 2019 13:19
Vote:
 

You could inherit CSVDataExporter and create your own implementation. NormalizeData is protected so you can override the implementation. Then replace the existing CSVDataExporter in the IOC container with your custom implemementation. 

#201083
Feb 05, 2019 12:10
Vote:
 

Hi David, thanks for replying.

I tried lots of ways to modify CSVDataExporter, but none of them really worked as I want. Not sure if I did it correctly though, but for now I just made a new TXTDataExporter class which inherits CSVDataExporter, and I'm doing my custom (first) normalization inside Export method of derived class and then return base's (CSVDataExporter) Export method (where dataTable getting normalized by native normalization method of CSVDataExporter), exports normal .txt of "text/plain".

I tried your idea, but it still gives me 2 same options.

I also noticed, that if my class has same MimeType or Name as CSVDataExporter, both options call my derived class Export.

I just want to intercept in CSVDataExporter's Export method now and normalize dataTable before. Without having duplicated CSV option in Export As or without having another (like TXT) option there as well.

#201092
Edited, Feb 05, 2019 15:49
Vote:
 

You should create your own implementation of DataExportingService.GetAllRegisteredExporters()

Ejecting and removing CSVDataExporter for DataExporterBase won't do the trick (Episerver.Forms 4.22).

#201138
Edited, Feb 06, 2019 17:36
Vote:
 

Here's some code based on Alloy and Epi 11.10.1.0.

public class DataExportingServiceInterceptor : DataExportingService
{
    public override IEnumerable<DataExporterBase> GetAllRegisteredExporters()
    {
        var exporters = base.GetAllRegisteredExporters();
        foreach (var exporter in exporters)
        {
            if (exporter.GetType() == typeof(CSVDataExporter))
            {
                continue;
            }

            yield return exporter;
        }
    }
}

Inside DependencyResolverInitialization.ConfigureContainer(), you need to add:

context.Services.Intercept<DataExportingService>(
    (locator, defaultImplementation) => new DataExportingServiceInterceptor());

And this is how it looks in edit mode:

#201173
Feb 07, 2019 16:11
Vote:
 

Hi Fujio,

In case several Exporters have same name, same MIMEType or FileExtension the Expoter which has lowest order will be chosen (The default Order of CSVDataExporter is 1000).

Unfortunately, the NormalizeData method in CSVDataExporter is not marked as virtual and so we have to override Export method.

Use the code below and implement your logic in MyNormalizeData method and it should work.

using EPiServer.Forms.EditView.DataTransfer;
using System;
using System.Data;
using System.IO;
using System.Text;

public class CustomCSVDataExporter : CSVDataExporter
{
    /// <summary>
    /// Order of the Exporter, default value is 1000. In case several Exporter have same name, same MIMEType or FileExtension, this Order is matter. 
    /// </summary>
    public override int Order => 1;

    public override string Export(DataTable dataTable)
    {
        var writer = new StringWriter();
        WriteColumnName(dataTable, writer);

        foreach (DataRow row in dataTable.Rows)
        {
            var sb = new StringBuilder();
            foreach (DataColumn column in dataTable.Columns)
            {
                sb.Append(MyNormalizeData(row[column.ColumnName] as string))
                    .Append(Separator);
            }
            writer.Write(sb.ToString().TrimEnd(Separator)); // remove the end comma by the last AppendFormat
            writer.Write(Environment.NewLine);
        }

        return writer.ToString();
    }

    private string MyNormalizeData(string value)
    {
        // TODO: your code goes here .......
        return value;
    }
}
#201279
Feb 12, 2019 8:04
Vote:
 

Thank you guys, I will difenetly come back to that issue as for now just went with additional Export As .TXT option, however intercepting existing CSV would be a "cleaner way". Cheers!

#201381
Feb 16, 2019 23:15
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.