Mahyar Zarifkar
Mahyar Zarifkar

Reputation: 196

How can i upload a file to server (asp.net web form) with ajax?

My project is an online mock toefl test. In speaking section I want to upload a recorded file (audio) to server. for recording im not using flash and its only js. I searched and find something useful but the server is php. and i cant turn the codes to asp.net (web form). please help me out.

In php i used this code in js :

function uploadAudio(mp3Data){
    var reader = new FileReader();
    reader.onload = function(event){
        var fd = new FormData();
        var mp3Name = encodeURIComponent('audio_recording_' + new Date().getTime() + '.mp3');
        console.log("mp3name = " + mp3Name);
        fd.append('fname', mp3Name);
        fd.append('data', event.target.result);
        $.ajax({
            type: 'POST',
            url: 'upload.php',
            data: fd,
            processData: false,
            contentType: false
        }).done(function(data) {
            //console.log(data);
            log.innerHTML += "\n" + data;
        });
    };      
    reader.readAsDataURL(mp3Data);
}

and this code in upload.php:

<?php
    if(!is_dir("recordings")){
        $res = mkdir("recordings",0777); 
    }

    // pull the raw binary data from the POST array
    $data = substr($_POST['data'], strpos($_POST['data'], ",") + 1);
    // decode it
    $decodedData = base64_decode($data);
    // print out the raw data, 
    //echo ($decodedData);
    $filename = urldecode($_POST['fname']);
    // write the data out to the file
    $fp = fopen('recordings/'.$filename, 'wb');
    fwrite($fp, $decodedData);
    fclose($fp);
?>

How can i do this in asp.net, tanks.

Upvotes: 2

Views: 4883

Answers (3)

Mahyar Zarifkar
Mahyar Zarifkar

Reputation: 196

I solved my problem. thank you guys. I used web services. in svc file i wrote these codes:

[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service
{
    [OperationContract]
    public void upload(string data)
    {
        byte[] base64EncodedBytes = System.Convert.FromBase64String(data);
        string strFileDestination = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath + "somefile.mp3";
        File.WriteAllBytes(strFileDestination, base64EncodedBytes);
    }
}

in js file i wrote this:

function uploadAudio(mp3Data) {
    var reader = new FileReader();
    reader.onload = function (event) {
        Service.upload(event.target.result, helloWorldCallback, onFail);
        function helloWorldCallback(result) {
            alert(result);
        }
        function onFail(e) {
            alert(e.get_message);
        }
    };
    reader.readAsDataURL(mp3Data);
} 

Upvotes: 1

Ross Brasseaux
Ross Brasseaux

Reputation: 4150

One method, and perhaps the most simple solution, is to just use the <asp:FileUpload> control, and hide it from view. Then again, although this works well if you want the user to choose the files they're uploading, it might not be the best solution if you want to implement some kind of HTML5 drag'n'drop solution, etc.

Coincidentally, I spent pretty much all of last week studying how to upload files via javascript to ASP.NET web forms. I developed a drag and drop interface that uses HTML5, and also developed a fail-over method with which the user could choose and upload their files via the <asp:FileUpload> control.

Due to the feature being low-priority, we only fully developed the <asp:FileUpload> control, but I'm happy to share that feature with you here:

HTML

We're going to create an ASP file upload control, and hide certain parts of it. The rest of it, we can add styles to (or do whatever in javascript and CSS) to make it look fancy and customized. The CONTINUE BUTTON

        <!-- Allow user to upload the file via the fallbackuploader -->
        <div id="fallbackUploader" class="uploader-item-fallbackuploader uploader-item fallbackuploader step-container">
            <div class="fallbackuploader-item-uploadcontrols fallbackuploader-item uploadcontrols">

                <!-- Uploader Label (note: this serves as the visible "choose files" button too) -->
                <label id="uploader_choose_files_button" class="uploadcontrols-item uploadcontrols-item-label button animated" for="mainContent_subContent_fbu_fileuploader">
                    Choose Files
                </label>
                <!-- Choose Files button (**NOTE: you'll want to make this control invisible. Try not to set the display to none, as that may cause ASP to omit rendering it -->
                <asp:FileUpload ID="fbu_fileuploader" CssClass="uploadcontrols-item-aspfileloader uploadcontrols-item aspfileloader" runat="server" />
                <!-- Continue button (NOTE: this button triggers the event that on the server side that will actually handle the file upload -->
                <asp:Button ID="fbu_fileuploaderButton" runat="server" Text="Continue" ClientIDMode="Static" 
                    CssClass="uploadcontrols-item-button-upload uploadcontrols-item-button uploadcontrols-item button-upload button continue-button hidden disabled animated" />
                <!-- Cancel button -->
                <div id="chooseFilesCancelButton" class="uploadcontrols-item-uploadcontrols-item-button 
                    uploadcontrols-item cancel-button hidden disabled button animated">
                    Go Back
                </div>
            </div>
        </div>

Javascript

// Organizational container for the file uploader controls.
var aspUploadControlsContainer = $('.fallbackuploader-item-uploadcontrols');
// ASP control that chooses and loads the file.
var aspFileLoader_ele = aspUploadControlsContainer.children('.uploadcontrols-item-aspfileloader'),
// element that represents the "choose files" button.
    aspUploaderChooseFilesLabel = aspUploadControlsContainer.find('.uploadcontrols-item-label'),
    // ASP button that loads the file
    aspFileLoaderButton_ele = aspUploadControlsContainer.children('.uploadcontrols-item-button'),
    // the element created by the actual ASP "<asp:FileUpload>" control tag.
    aspFileUploadControl_ele = aspUploadControlsContainer.find('input.uploadcontrols-item-aspfileloader'),
    // the message/alert container
    messagebox_ele = $('.uploader-item-messagebox');

// ------------------------------------------------------------
//  Bind the 'click' and 'change' events to the file uploader
// ------------------------------------------------------------
function bindAspUploadControlEvents() {
    aspFileLoader_ele.on('change', function () { // add the on-change event for the file uploader.
        console.log('File changed ...');
        if (!aspUploaderChooseFilesLabel.hasClass('upload-disabled')) {
            console.log('Choose-files label not disabled ...');
            fileSelected(); // perform the file-selected actions.
        }
    });
};


// ------------------------------------------------------------
//  Validate the selected file name and adjust the uploader.
// ------------------------------------------------------------
function fileSelected() {
    console.log('File selected...');
    var f = aspFileLoader_ele.val() || '';
    f = f.replace('C:\\fakepath\\', '') || ''; // get the file name <-- ASP.NET masks the path as C:\\fakepath\\ for security purposes...we'll just take that part out.
    var xlRegex = /.(xlsx|xls)$/i; // set the regex to test for accepted file extensions.

    if (f.length && !(f.match(xlRegex))) {
        // --------------------------- FAILED - show a message -----------------------------------------------------------------
        console.log('File-name invalid. Displaying error message ...');
        convertCFlabelToButton(); // <-- converting the label to a button and visa versa is probably a round-about way of doing what we wanted, but we were doing some other stuff with it that kind of made it a necessary evil :)
        deactivateChooseFilesCancelButton(); // if nothing selected, disable and hide cancel button <-- these functions just do some fluffy stuff that you probably won't need.
        deactivateUploaderContinueButton(function () { // if nothing selected, disable and hide continue button <-- these functions just do some fluffy stuff that you probably won't need.
            messagebox_ele.text("You've selected a file with an invalid file name. Please make sure the file extension ends with \".xlsx\".").show(); // show the error message.
        });

    } else if (f.length && f.match(xlRegex)) {
        // --------------------------- PASSED ----------------------------------------------------------------- 
        console.log('File-name validated. Hiding messages...');
        messagebox_ele.text('').hide(); // reset and hide any messages
        console.log('Messages hidden.');
        convertCFbuttonToLabel(f, function () { // this converts the button to a label with the given file name as its text
            activateUploaderContinueButton(function () { // show and enable the choose-files continue-button
                activateChooseFilesCancelButton() // show and enable the choose-files cancel-button
            });
        });
    } else {
        // --------------------------- FAILED - hide message -----------------------------------------------------------------
        console.log('No file detected. Returning to default state ...');
        messagebox_ele.text('').hide(); // hide any messages
        // reset the label to defaults
        convertCFlabelToButton();

        // ------------------------------------------------------------------------------------------------------------------------------
    };
}

CODE-BEHIND

Now we just need to add the VB.NET (or C#) to handle the click-event for the continue button.

Protected Sub fbu_fileuploaderButton_Click(sender As Object, e As EventArgs) Handles fbu_fileuploaderButton.Click
        If fbu_fileuploader.HasFile Then
            Dim FileName As String = Path.GetFileName(Path.GetRandomFileName())
            Dim Extension As String = Path.GetExtension(fbu_fileuploader.PostedFile.FileName)
            Dim FolderPath As String = ResolveUrl("~/" & ConfigurationManager.AppSettings("FolderPath"))
            Dim FilePath As String = Server.MapPath(FolderPath + FileName)
            fbu_fileuploader.SaveAs(FilePath)
            GetExcelSheets(FilePath, fbu_fileuploader.PostedFile.FileName, FileName, Extension, "Yes")
        End If
    End Sub

Other Caveats

We did a couple things in the above code that I did not explain, such as the "FolderPath" application setting (we used this in CODE-BEHIND section to determine where the file should be saved). If you've never used application settings in the web.config, it's very simple. For the sake of the above example, we would add the following snippet between our <configuration> tags:

<appSettings>
    <add key="FolderPath" value="uploads/"/>
  </appSettings>

I can then access the value of this appSetting using

ResolveUrl("~/" & ConfigurationManager.AppSettings("FolderPath"))

or

ResolveUrl(String.Format("~/{0}", ConfigurationManager.AppSettings("FolderPath")))

Also, I stopped with the function to "getExcelSheets" because that's more specific to my application, and probably beyond the scope of this tutorial.


Additional Resources

I have a good habit of methodically saving useful bookmarks. Here is what I have from my "File Uploader" section...

Upvotes: 1

Rafet
Rafet

Reputation: 926

You can use jQuery File Uploader on an aspx page. Your client can simply communicate withe an ashx handler at the server side.

https://evolpin.wordpress.com/2011/09/11/asp-net-ajax-file-upload-using-jquery-file-upload-plugin/

Upvotes: 2

Related Questions