Загрузка файла с инструментарием Ajax не вызывается

У меня есть два файла ulopads ajaxtoolkit на одной странице, например

 <ajaxToolkit:AjaxFileUpload
        id="AjaxFileUpload1"
        AllowedFileTypes="jpg,jpeg,gif,png"
        OnUploadComplete="ajaxUpload2_OnUploadComplete"
        runat="server"  />
         <ajaxToolkit:AjaxFileUpload
        id="ajaxUpload1"
        AllowedFileTypes="jpg,jpeg,gif,png"
        OnUploadComplete="ajaxUpload1_OnUploadComplete"
        runat="server"  />

и код позади

protected void ajaxUpload2_OnUploadComplete(object sender, AjaxControlToolkit.AjaxFileUploadEventArgs e)
    {

        string filePath = "~/Images/" + e.FileName;
        filePath = filePath.Split('\\').Last();
        Session["img2"] = filePath.ToString();
        AjaxFileUpload1.SaveAs(MapPath(filePath));

    }

    protected void ajaxUpload1_OnUploadComplete(object sender, AjaxControlToolkit.AjaxFileUploadEventArgs e)
    {

        string filePath = "~/Images/" + e.FileName;
        filePath = filePath.Split('\\').Last();
        Session["img1"] = filePath.ToString();
        ajaxUpload1.SaveAs(MapPath(filePath));

    }

Вопрос в том, когда я использую загрузку AjaxFileUpload1, он работает и вызывает метод void ajaxUpload2_OnUploadComplete, но если я использую ajaxUpload1, метод ajaxUpload2_OnUploadComplete вызывается снова, но метод ajaxUpload1 не вызывается

Почему??

Спасибо.


person COLD TOLD    schedule 25.05.2012    source источник


Ответы (3)


Вчера у нас возникла такая же проблема, и мы обнаружили, что у вас не может быть более одного экземпляра AjaxFileUpload на одной странице.

Если вы посмотрите на исходный код, вы увидите, что этот элемент управления использует постоянный GUID для идентификации своих событий. Поскольку GUID является константой, все экземпляры AjaxFileUpload используют один и тот же GUID. ..

Результат:

первый экземпляр глотает все события ...

Вот GUID в действии:

private const string ContextKey = "{DA8BEDC8-B952-4d5d-8CC2-59FE922E2923}";

(...)

if (this.Page.Request.QueryString["contextkey"] == ContextKey && this.Page.Request.Files.Count > 0)
person Sylvain Rodrigue    schedule 31.05.2012
comment
@SRo У меня такая же проблема .. Не могли бы вы посоветовать мне, как я могу это исправить? - person Vignesh Kumar A; 07.03.2014
comment
@Vignesh Kumar: В то время я не нашел решения. Я просто заменил элемент управления Ajax Toolkit Upload на простой элемент управления загрузкой файлов ASP.NET (я правильно помню :) Ура. - person Sylvain Rodrigue; 07.03.2014
comment
@VigneshKumar: принятый ответ неверен; у вас может быть несколько экземпляров AjaxFileUpload на странице. См. Мой ответ ниже, это действительно легко сделать - person Byron Jones; 05.09.2016

Мы настроили набор инструментов за сентябрь 2012 года следующим образом - надеюсь, что это временный обходной путь и что он будет исправлен в следующем выпуске:

СТАРЫЙ

private const string ContextKey = "{DA8BEDC8-B952-4d5d-8CC2-59FE922E2923}";

НОВЫЙ

private string ContextKey = "";

СТАРЫЙ

public AjaxFileUpload()
            : base(true, HtmlTextWriterTag.Div)
        {
        }

НОВЫЙ

public AjaxFileUpload()
            : base(true, HtmlTextWriterTag.Div)
        {
            if (HttpContext.Current.Items["lastAjaxFileUploadContextKey"] == null)
            {
                HttpContext.Current.Items["lastAjaxFileUploadContextKey"] = 1;
            }
            else
            {
                HttpContext.Current.Items["lastAjaxFileUploadContextKey"] = (int)HttpContext.Current.Items["lastAjaxFileUploadContextKey"] + 1;
            }

            ContextKey = HttpContext.Current.Items["lastAjaxFileUploadContextKey"].ToString();
        }
person Gray Connective Support    schedule 11.12.2012

На самом деле существует способ использовать несколько элементов управления AjaxFileUpload на одной странице, при этом каждый элемент управления запускает собственное событие. Решение очень простое; он включает в себя переопределение одной из клиентских функций Microsoft для элемента управления AjaxFileUpload, чтобы ввести информацию об элементе управления, который фактически вызвал событие завершения загрузки, а затем использование одного обработчика событий для всех элементов управления AjaxFileUpload в качестве «коммутатора», который впоследствии сработает правильный обработчик событий для элемента управления, создавшего событие на стороне сервера.

Вот как это сделать:

Добавьте этот блок сценария где-нибудь после элемента заголовка вашей страницы. Если вы используете главные страницы, поместите это в заполнитель для содержимого HTML:

<script type="text/javascript">
    Sys.Extended.UI.AjaxFileUpload.Control.prototype.doneAndUploadNextFile = function (c) {
        var a = new XMLHttpRequest, b = this;
        a.open("POST", "?contextKey=" + this._contextKey + "&done=1&guid=" + c._id + "&uplCtrlID=" + b.get_id(), true);
        a.onreadystatechange = function () {
            if (a.readyState == 4) if (a.status == 200) {
                b.raiseUploadComplete(Sys.Serialization.JavaScriptSerializer.deserialize(a.responseText));
                b._processor.startUpload()
            }
            else {
                b.setFileStatus(c, "error", Sys.Extended.UI.Resources.AjaxFileUpload_error);
                b.raiseUploadError(a);
                throw "error raising upload complete event and start new upload";
            }
        };
        a.send(null);
    }
</script>

Этот код - та же функция, которая используется для вызова вашей страницы и запуска события UploadComplete, только измененная для добавления дополнительного параметра - uplCtrlID, который будет содержать идентификатор элемента управления, который ДЕЙСТВИТЕЛЬНО вызвал событие.

Настройте код на стороне сервера следующим образом:

//set the OnUploadComplete property on all of your AjaxFileUpload controls to this method
protected void anyUploader_UploadComplete(object sender, AjaxFileUploadEventArgs e)
    {
        //call the correct upload complete handler if possible
        if (Request.QueryString["uplCtrlID"] != null)
        {
            //uplCtrlID (the query string param we injected with the overriden JS function)
            //contains the ID of the uploader.
            //We'll use that to fire the appropriate event handler...
            if (Request.QueryString["uplCtrlID"] == FileUploaderA.ClientID)
                FileUploaderA_UploadComplete(FileUploaderA, e);
            else if (Request.QueryString["uplCtrlID"] == FileUploaderB.ClientID)
                FileUploaderB_UploadComplete(FileUploaderB, e);
            //etc (or use a switch block - whatever suits you)
        }
    }
    protected void FileUploaderA_UploadComplete(AjaxFileUpload sender, AjaxFileUploadEventArgs e)
    {
        //logic here
    }
    protected void FileUploaderB_UploadComplete(AjaxFileUpload sender, AjaxFileUploadEventArgs e)
    {
        //logic here
    }

Все готово. Несколько элементов управления AjaxFileUpload на одной странице, никаких проблем.

person Byron Jones    schedule 07.06.2013