Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use the ContextKeys property for the AjaxFileUpload control?

I started looking at the AjaxFileUpload control, specifically the ContextKeys property. However, I do not understand how to use it.

The documentation says of AjaxFileUpload that the ContextKeys is used to pass information to the server when a file is uploaded. But no examples are provided. Are there any examples online that I could look at?

like image 471
Paco Mendez Avatar asked Oct 07 '22 04:10

Paco Mendez


1 Answers

Though such functionality not implemented (I believe it was planned but by some reasons was postponed), nothing protect you from implement it yourself. To do this you need to download AjaxControlToolkit source code and tweak it for your needs.

There will be a lot of points so you may to prepare a cup of coffee before :)

I'll show changes with name of file that must being changed.

Server/AjaxControlToolkit/AjaxFileUpload/AjaxFileUpload.cs file

First of all, add ContextKeys property to the AjaxFileUploadEventArgs.cs file (it located in same folder):

/// <summary>
/// Gets or sets the context keys.
/// </summary>
public string ContextKeys
{
    get;
    set;
}

After that open the AjaxFileUpload class code and change the OnPreRender method. Here is a part of this method with custom modifications:

var eventArgs = new AjaxFileUploadEventArgs(guid, AjaxFileUploadState.Success,
"Success", uploadedFile.FileName,
uploadedFile.ContentLength, uploadedFile.ContentType,
stream.ToArray());

// NEW CODE HERE
eventArgs.ContextKeys = this.Page.Request.Form["contextKeys"];

That's all changes in server code we need. Now we need to modify the Sys.Extended.UI.AjaxFileUpload client class (file AjaxFileUpload.pre.js )

Firstly let's modify _html5UploadFile method as below:

_html5UploadFile: function (fileItem) {
    this._guid = Sys.Extended.UI.AjaxFileUpload.utils.generateGuid();

    var uploadableFile = fileItem.get_fileInputElement();

    var fd = new FormData();
    fd.append("fileId", uploadableFile.id);
    fd.append("Filedata", uploadableFile.file);

    if (this.contextKeys) {
        if (typeof this.contextKeys !== "string") {
            this.contextKeys = Sys.Serialization.JavaScriptSerializer.serialize(this.contextKeys);
        }
        fd.append("contextKeys", this.contextKeys);
    }

    $common.setVisible(this._progressBar, true);
    this._setDisableControls(true);
    this._html5SetPercent(0);
    this._setStatusMessage(String.format(Sys.Extended.UI.Resources.AjaxFileUpload_UploadingHtml5File, uploadableFile.file.name, Sys.Extended.UI.AjaxFileUpload.utils.sizeToString(uploadableFile.file.size)));

    var url = this._postBackUrl;
    if (url.indexOf("?") != -1)
        url += "&";
    else
        url += "?";

    this._webRequest = new Sys.Net.WebRequest();
    this._executor = new Sys.Net.XMLHttpExecutor();
    this._webRequest.set_url(url + 'contextkey=' + this._contextKey + '&guid=' + this._guid);
    this._webRequest.set_httpVerb("POST");
    this._webRequest.add_completed(this.bind(this._html5OnRequestCompleted, this));

    //this._executor.add_load(this.bind(this._html5OnComplete, this));
    this._executor.add_progress(this.bind(this._html5OnProgress, this));
    this._executor.add_uploadAbort(this.bind(this._html5OnAbort, this));
    this._executor.add_error(this.bind(this._html5OnError, this));
    this._webRequest.set_executor(this._executor);

    this._executor.executeRequest(fd);
}

As you can see above, we adding contextKeys to form data, posted with Ajax request.

The we need to modify the _uploadInputElement method:

_uploadInputElement: function (fileItem) {

    var inputElement = fileItem.get_fileInputElement();
    var uploader = this;
    uploader._guid = Sys.Extended.UI.AjaxFileUpload.utils.generateGuid();
    setTimeout(function () {
        uploader._setStatusMessage(String.format(Sys.Extended.UI.Resources.AjaxFileUpload_UploadingInputFile, Sys.Extended.UI.AjaxFileUpload.utils.getFileName(inputElement.value)));
        uploader._setDisableControls(true);
        uploader.setThrobber(true);
    }, 0);

    var url = uploader._postBackUrl;
    if (url.indexOf("?") != -1)
        url += "&";
    else
        url += "?";

    uploader._createVForm();
    uploader._vForm.appendChild(inputElement);

    if (this.contextKeys) {
        if (typeof this.contextKeys !== "string") {
            this.contextKeys = Sys.Serialization.JavaScriptSerializer.serialize(this.contextKeys);
        }

        var contextKeysInput = document.createElement("input");
        contextKeysInput.setAttribute("type", "hidden");
        contextKeysInput.setAttribute("name", "contextKeys");
        contextKeysInput.setAttribute("value", this.contextKeys);

        uploader._vForm.appendChild(contextKeysInput);
    }

    uploader._vForm.action = url + 'contextkey=' + this._contextKey + '&guid=' + this._guid;
    uploader._vForm.target = uploader._iframeName;

    setTimeout(function () {
        uploader._vForm.submit();
        uploader._waitTimer = setTimeout(function () { uploader._wait() }, 100);
    }, 0);
}

After all these changes you can set ContextKeys property in code-behind and get it value from AjaxFileUploadEventArgs argument of the UploadComplete event as below:

protected void Page_Load(object sender, EventArgs e)
{

    if (!IsPostBack && !AjaxFileUpload1.IsInFileUploadPostBack)
    {
        AjaxFileUpload1.ContextKeys = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(new Dictionary<string, string> { { "1", "First" }, { "2", "Second" } });
    }

protected void AjaxFileUpload1_OnUploadComplete(object sender, AjaxFileUploadEventArgs file)
{
    if (!string.IsNullOrEmpty(file.ContextKeys))
    {
        var contextKeys = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<Dictionary<string, string>>(file.ContextKeys);
    }

Also, if you'll implement OnClientUploadStarted client-side event as proposed here link, you may pass to server your contextKeys from client:

 function uploadStarted(sender, args) {
      sender.contextKeys = { "first": "1", "second": "2" };
 }
like image 159
Yuriy Rozhovetskiy Avatar answered Oct 10 '22 02:10

Yuriy Rozhovetskiy