Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
387 views
in Technique[技术] by (71.8m points)

asp.net - 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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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" };
 }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...