On Save prevent page redirect

I'm using the Angular Typescript Spreadsheet with AspNetCore.Mvc backend and I would like to prevent a page redirect to the SaveUrl.

The spreadsheet is part of a Mat-Stepper control and I need to continue the workflow post save... how do I do this? 

Backend code:
        [HttpPost]
        public ActionResult Save(SaveSettings saveSettings)
        {
            var returnVal = 0;
            ExcelEngine excelEngine = new ExcelEngine();
            IApplication application = excelEngine.Excel;
            try
            {
                // Convert Spreadsheet data as Stream
                Stream fileStream = Workbook.Save<Stream>(saveSettings);
                IWorkbook workbook = application.Workbooks.Open(fileStream);
                var filePath = "";
                returnVal = OpenCloseFiles.GetFolderPathFromAssembly(saveSettings.FileName, out filePath);
                if (returnVal < 0)
                    return new ObjectResult(returnVal);

                FileStream outputStream = new FileStream(filePath, FileMode.Create);
                workbook.SaveAs(outputStream);

                return new ObjectResult(returnVal);
            }
            catch (Exception ex)
            {
                return new ObjectResult(returnVal);
            }
        }

Frontend:
    @ViewChild('excelupload')
    public spreadsheetObj: SpreadsheetComponent;

    excelCreated() {
        this.spreadsheetObj.allowOpen = true;
        this.spreadsheetObj.openUrl = this.openUrl;
        this.spreadsheetObj.saveUrl = this.saveUrl;
        this.spreadsheetObj.showFormulaBar = false;
        this.spreadsheetObj.showSheetTabs = false;
        this.spreadsheetObj.cellFormat({ fontWeight: 'bold', textAlign: 'center' }, 'A1:Z1');
        this.spreadsheetObj.cellFormat({ textAlign: 'center' }, 'A1:Z1');
        this.spreadsheetObj.beforeSave = this.beforeSave;
        this._changeDetectorRef.markForCheck();
    }

    beforeSubmit(): number {
        const saveOptions: SaveOptions = {
            fileName: this.uploadExcelFileName,
            saveType: 'Xlsx',
            url: this._dataService.baseUrl + '/tables/syncfusion/save',
        }
        this.spreadsheetObj.save(saveOptions);
        return 1;
    }
    beforeSave(args: BeforeSaveEventArgs) {
        debugger;
        args.isFullPost = false
    };


10 Replies

MV Madhan Venkateshan Syncfusion Team June 22, 2020 11:03 AM UTC

Hi Hugh Proctor, 
 
Good day to you. 
 
You can prevent the page redirect by setting ‘args.isFullPost’ to ‘false’ in ‘beforeSave’ event and if you want to prevent the excel file to download in the browser set ‘args. needBlobData’ to true. We have prepared a sample based on requirement, please check with the below sample link. 
 
App.component.html 
<ejs-spreadsheet #default [openUrl]="openUrl"  [saveUrl]="saveUrl" (beforeSave)="beforeSave($event)" (created)="created()"> 
 
App.component.ts 
beforeSave(args) { 
  args.isFullPost = false; 
  args.needBlobData = true; 
} 
 
 
 
Please check whether the above sample will resolve your issue, if still persists please share issue reproducible sample, So that we can sort out and provide you the better solution quickly.  
 
Regards, 
Madhan V 



HP Hugh Proctor June 24, 2020 05:19 PM UTC

Hi Madhan,

I'm testing it out and I'm not sure its what I'm after... not sure..

So... I have the excel in the Syncfusion spreadsheet... 
I hit save
It should save on the server
Not save and get... just save
No redirect..

Like an Ajax post or Async Post or an Api Post.

At the moment in the Chrome console I've got this:
blob:http://localhost:4200/720dfcea-e3a9-4a62-9b1a-2bc613e3322c

localhost:4200 is my local Angular website... so not sure why it's referencing that.. my Api is on localhost:6140

Any ideas?

Hugh



MV Madhan Venkateshan Syncfusion Team June 25, 2020 12:04 PM UTC

Hi Hugh, 
 
Good day to you. 
 
Query #1: just save No redirect.. 
 
We are not able to reproduce in our end, we have prepared a video demonstration of your requirement. Please check the below link. 
 
 
 
 
Please check the above sample link, if issue still persist, please provide issue replicable sample. 
 
Query #2: At the moment in the Chrome console I've got this so not sure why it's referencing that.. my Api is on localhost:6140 
 
We suspect that this issue may occur when your dependent project may be hosted indirectly and making this request and please ensure this issue in your end. please share any issue reproducible sample to check in our end. 
 
Regards, 
Madhan V 



HP Hugh Proctor June 25, 2020 02:00 PM UTC

Thanks Madhan,

Yeah, I see how your making your version work, but it's not a real world of how one would actually go about using this..

I currently have a very large Api - that is in .Net 4.6.1 .. so I've hacked it together to use .NetCore.MVC for this SyncFusion... I use ApiController so don't have an MVC Controller, but I managed to do a work around for that.

I also don't have a Files folder on my server... the Excel uploads go into an ExcelUploads folder, but again, I'm trying to do a work around.

I'm also not saving the file onto the Server upon Opening the Excel document, as you can imagine.. I only want to save it when they save it.

This Excel function once saved on the server, the user then moves to another Step in the Process, which based upon Step 1 - a Form (defines the type of Excel document to be uploaded), Step 2 - the Excel upload, then Step 3 commits steps 1 & 2 to the server, grabs the Excel document (in the API and deletes it) sends into a backend WCF service which extracts the data from the Excel. Based upon the type of data in the Excel file, it then Saves data into different tables and deletes the Excel document and finally uploads it on to Microsoft OneDrive via their API.

And this whole thing is nested within Components, in a tabbed page full of other various bits of business information.

So it's pretty complex.

So... I can't do this, because it suggests saving the Excel document onto the Server when the document is opened on the Client. 

   createdExcel() {
        var request = new XMLHttpRequest();
        request.responseType = "blob";
        request.onload = () => {
            var file = new File([request.response], "Sample.xlsx");
            this.spreadsheetObj.open({ file: file });
        }
        request.open("GET", this._dataService.baseUrl + '/tables/syncfusion/open/Files/' + "Sample.xlsx");
        request.send();
    }

In addition, this url "http://localhost:55367/Files/" + "Sample.xlsx" will never exist... it's part of a large Api that I can't split because I need to use the Excel in a different process


HP Hugh Proctor June 25, 2020 04:56 PM UTC

So basically, your code allows for two scenarios:

1. It saves without overriding the arg.isFullPost -> this hits the server with SaveSettings values but does a full page redirect, which is rubbish and completely useless

or 

2. It saves with overriding the arg.isFullPost -> this hits the server without SaveSettings values and some how I have to hack the values out as Multipart Form Data Stream

This is very poor programming on your part..

Why on earth did you think that either of these two scenarios would be suitable for real use???

To add to the pain... it takes an entire day to get a response from you guys.


MV Madhan Venkateshan Syncfusion Team June 28, 2020 10:43 AM UTC

Hi Hugh Proctor, 
 
Good day to you. 
 
We would you inform that the ‘beforeSave’ event is never called to set ‘isFullPost’ to false, as per your code snippets, you have dynamically assigned the beforeSave event, we suggest you to define this event initially to resolve your issue. Please refer the below code snippets. 
 
<ejs-spreadsheet #default (beforeSave)="beforeSave($event)" (created)="created()"> // add beforeSave event initially like this 
  
excelCreated() { 
        this.spreadsheetObj.allowOpen = true; 
        this.spreadsheetObj.openUrl = this.openUrl; 
        this.spreadsheetObj.saveUrl = this.saveUrl; 
        this.spreadsheetObj.showFormulaBar = false; 
        this.spreadsheetObj.showSheetTabs = false; 
        this.spreadsheetObj.cellFormat({ fontWeight: 'bold', textAlign: 'center' }, 'A1:Z1'); 
        this.spreadsheetObj.cellFormat({ textAlign: 'center' }, 'A1:Z1'); 
        this.spreadsheetObj.beforeSave = this.beforeSave; // Remove this line 
        this._changeDetectorRef.markForCheck(); 
    } 
 
Regards, 
Madhan V 



HP Hugh Proctor June 28, 2020 11:27 AM UTC

Hi Madhan,

I had already removed that...

I solved the issue myself by hacking the Api code..

If you do what I need it to do... which is not to Save upon opening the document but only when the user clicks Save, then your control sends the data back to the server as a Multipart/form-data

This means that the SaveSettings object is null.. and the way to get the details is to get some of the values using an InMemoryMultipartFormDataStreamProvider

I then have to get the JSONData from the HttpContext Form... like so:

        [HttpPost]
        public async Task<ActionResult> Save(SaveSettings saveSettings)
        {
           // Check if the request contains multipart/form-data.  
            if (!Request.Content.IsMimeMultipartContent())  
            {
                return new ObjectResult(null);
            }

            var provider = await Request.Content.ReadAsMultipartAsync(new InMemoryMultipartFormDataStreamProvider());  
            //access form data  
            NameValueCollection formData = provider.FormData;

            saveSettings = new SaveSettings
            {
                FileName = formData.Get("fileName"),
                SaveType = SaveType.Xlsx,
                SaveUrl = formData.Get("url"),
                JSONData = System.Web.HttpContext.Current.Request.Form.Get("JSONData")
            };

            var returnVal = 0;
            ExcelEngine excelEngine = new ExcelEngine();
            IApplication application = excelEngine.Excel;
            try
            {
                // Convert Spreadsheet data as Stream
                using (Stream fileStream = Workbook.Save<Stream>(saveSettings))
                {
                    IWorkbook workbook = application.Workbooks.Open(fileStream);
                    returnVal = OpenCloseFiles.GetFolderPathFromAssembly(saveSettings.FileName, out string filePath);
                    if (returnVal < 0)
                        return new ObjectResult(returnVal);

                    using (FileStream outputStream = new FileStream(filePath, FileMode.Create))
                    {
                        workbook.SaveAs(outputStream);
                        workbook.Close();
                        outputStream.Close();
                    }
                    fileStream.Close();
                }
                return new ObjectResult(returnVal);
            }
            catch (Exception ex)
            {
                return new ObjectResult(returnVal);
            }
        }
    }


MV Madhan Venkateshan Syncfusion Team June 29, 2020 09:49 AM UTC

Hi Hugh Proctor, 
 
Thanks for your update. We are happy to hear that your reported issue has been resolved. 
  
Regards, 
Madhan V 



HP Hugh Proctor June 29, 2020 05:36 PM UTC

Yeah, no thanks to the support team, this communication or thread or the documentation...  a total hack that is a work around to the poor implementation of your team.

Very disappointing and I'll be requesting a partial refund due to poor customer service


PG Pon Geetha A J Syncfusion Team July 15, 2020 10:11 AM UTC

Hi Hugh, 
  
We will consider your concern and update our documentation in one of our releases.  We request you to contact your Syncfusion Account Manager for refund requests, 
  
Regards, 
Geetha 


Loader.
Up arrow icon