Значения Ajax Upload w / C # ashx возвращает 'Индекс был вне диапазона. Должен быть неотрицательным и меньшим, чем размер коллекции. ошибка - PullRequest
2 голосов
/ 06 августа 2011

Я играл со скриптом загрузки AJAX от Valum: http://valums.com/ajax-upload/

Это помечает все флажки для меня, не используя ужасный flash-объект swfupload для одного. У меня есть точка JS в моем скрипте .ashx (который я не могу отладить из-за любви и денег). Вот что у меня в .ashx:

аватар открытого класса: IHttpHandler, System.Web.SessionState.IRequiresSessionState {

public void ProcessRequest (HttpContext context) {
    //Debugger.Break();

string result = "{\"success\":true}";
    string path = HttpContext.Current.Server.MapPath("/client/vault/" + Helpers.CurrentClientHash(context.Session["SessionHash"].ToString()) + "/users/" + context.Session["SessionHash"].ToString() + "/");
    string saveLocation = string.Empty;
    string fileName = string.Empty;

    try
    {
        int length = 4096;
        int bytesRead = 0;
        Byte[] buffer = new Byte[length];

        //This works with Chrome/FF/Safari
        // get the name from qqfile url parameter here
        Debugger.Break();
        fileName = context.Request["params"];
        Debug.Write(fileName);

        saveLocation = context.Server.MapPath(path) + fileName;

        try
        {
            using (FileStream fileStream = new FileStream(saveLocation, FileMode.Create))
            {
                do
                {
                    bytesRead = context.Request.InputStream.Read(buffer, 0, length);
                    fileStream.Write(buffer, 0, bytesRead);
                }
                while (bytesRead > 0);
            }
        }
        catch (UnauthorizedAccessException ex)
        {
            // log error hinting to set the write permission of ASPNET or the identity accessing the code
            result = result.Replace("true","false, \"error\":" + ex.Message + " " + ex.InnerException + " " + ex.StackTrace.ToString());
        }
}
catch
{
    try
        {
            //This works with IE
            fileName = Path.GetFileName(context.Request.Files[0].FileName);
            saveLocation = context.Server.MapPath(path) + fileName;
            context.Request.Files[0].SaveAs(saveLocation);
        }
    catch (Exception ex)
        {
            result = result.Replace("true", "false, \"error\":" + ex.Message + " " + ex.InnerException);
        }
}
context.Response.Write(result);
}

public bool IsReusable {
    get {
        return false;
    }
}

}

Этот код был любезно предложен другим пользователем скрипта Valum, потому что он поставляется с PHP-компонентами на стороне сервера. Когда я запускаю загрузчик, я получаю это в консоли:

[uploader] responseText = {"success": false, "error": индекс не найден спектр. Должен быть неотрицательным и меньшим, чем размер коллекции. Имя параметра: индекс}

... и загрузка, конечно, не удалась. Я уверен, что это как-то связано с FileStream, но без значимой отладки я не могу найти проблему. Я думаю это может быть из-за того, что файл не извлекается .ashx, но он в параметрах:

bust uploader...

Итак, у меня есть два вопроса, если можно:

  1. Кто-нибудь может сразу увидеть, где или почему я получаю исключение индекса?
  2. Если нет, как я могу отладить эту вещь? Я не могу просто запустить отладчик из VS2010, потому что не загружается JS. Я, очевидно, тоже не могу пойти прямо к ашу ... Есть идеи?

Помощь оценена :) 1033 *

Ответы [ 3 ]

4 голосов
/ 08 августа 2011

К сожалению, я никогда не решал это. Я удалил скрипт Valams и выбрал Plupload .

Plupload стал проще, он поддерживает HTML5, Flash, Gears и BrowserPlus. Это было ежу понятно, в конце концов. Вот рабочий код для тех, кто ищет виджет CJ AJAX Uploader:

<script type="text/javascript" src="/js/jquery.min.js"></script>

    <script type="text/javascript" src="http://bp.yahooapis.com/2.4.21/browserplus-min.js"></script>
    <script type="text/javascript" src="/js/plupload.js"></script>

    <script type="text/javascript" src="/js/plupload.html5.js"></script>
    <script type="text/javascript" src="/js/plupload.gears.js"></script>
    <script type="text/javascript" src="/js/plupload.browserplus.js"></script>
    <script type="text/javascript" src="/js/plupload.silverlight.js"></script>
    <script type="text/javascript">
        // Custom example logic
        function $(id) {
            return document.getElementById(id);
        }


        var uploader = new plupload.Uploader({
            runtimes: 'gears,html5,silverlight,browserplus',
            browse_button: 'pickfiles',
            max_file_size: '2mb',
            multi_selection: false,
            url: '/components/uploadify/avatar.ashx',
            silverlight_xap_url: '/js/plupload.silverlight.xap',
            filters: [
                { title: "Image files", extensions: "jpg,gif,png" }
            ]
        });

        uploader.bind('Init', function (up, params) {
            $('filelist').innerHTML = "<div>Current runtime: " + params.runtime + "</div>";
        });

        uploader.bind('FilesAdded', function (up, files) {
            for (var i in files) {
                $('filelist').innerHTML += '<div id="' + files[i].id + '">' + files[i].name + ' (' + plupload.formatSize(files[i].size) + ') <b></b></div>';
            }
        });

        uploader.bind('UploadFile', function (up, file) {
            $('uploader').innerHTML += '<input type="hidden" name="file-' + file.id + '" value="' + file.name + '" />';
        });

        uploader.bind('UploadProgress', function (up, file) {
            $(file.id).getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>";
        });

        uploader.bind('FileUploaded', function (up, file, obj) {
            alert("I've done uploading stuff...");

        });

        $('uploadfiles').onclick = function () {
            uploader.start();
            return false;
        };

        uploader.init();
</script>

И C # .ashx ...

public class avatar : IHttpHandler, System.Web.SessionState.IRequiresSessionState {

    public void ProcessRequest (HttpContext context) {
        string path = "/a/path/to/someplace/";
        if (context.Request.Files.Count > 0)
        {
            int chunk = context.Request["chunk"] != null ? int.Parse(context.Request["chunk"]) : 0;
            string fileName = context.Request["name"] != null ? context.Request["name"] : string.Empty;

            HttpPostedFile fileUpload = context.Request.Files[0];

            var uploadPath = path;
            using (var fs = new FileStream(Path.Combine(uploadPath, fileName), chunk == 0 ? FileMode.Create : FileMode.Append))
            {
                var buffer = new byte[fileUpload.InputStream.Length];
                fileUpload.InputStream.Read(buffer, 0, buffer.Length);

                fs.Write(buffer, 0, buffer.Length);
            }
        }

    }

    public bool IsReusable {
        get {
            return false;
        }
    }

}

Возможно, стоит отметить, что если вы хотите получить доступ к сеансу в .ashx, вам просто нужно добавить SessionState.IRequiresSessionState, как показано.

Я надеюсь, что читатели найдут это полезным:)

3 голосов
/ 01 декабря 2011

Я использовал обработчик ASHX, предоставленный Сайедом Баширом в его блоге . Работает отлично.

  public void ProcessRequest(HttpContext context)
  {
      const string path = "Capture/Images";
      String filename = HttpContext.Current.Request.Headers["X-File-Name"];
      if (string.IsNullOrEmpty(filename) && HttpContext.Current.Request.Files.Count <= 0)
      {
          context.Response.Write("{success:false}");
      }
      else
      {
          string mapPath = HttpContext.Current.Server.MapPath(path);
          if (Directory.Exists(mapPath) == false)
          {
              Directory.CreateDirectory(mapPath);
          }
          if (filename == null)
          {
              //This work for IE
              try
              {
                  HttpPostedFile uploadedfile = context.Request.Files[0];
                  filename = uploadedfile.FileName;
                  uploadedfile.SaveAs(mapPath + "\\" + filename);
                  context.Response.Write("{success:true, name:\"" + filename + "\", path:\"" + path + "/" + filename + "\"}");
              }
              catch (Exception)
              {
                  context.Response.Write("{success:false}");
              }
          }
          else
          {
              //This work for Firefox and Chrome.
              FileStream fileStream = new FileStream(mapPath + "\\" + filename, FileMode.OpenOrCreate);
              try
              {
                  Stream inputStream = HttpContext.Current.Request.InputStream;
                  inputStream.CopyTo(fileStream);
                  context.Response.Write("{success:true, name:\"" + filename + "\", path:\"" + path + "/" + filename + "\"}");
              }
              catch (Exception)
              {
                  context.Response.Write("{success:false}");
              }
              finally
              {
                  fileStream.Close();
              }
          }
      }
  } 
1 голос
/ 06 августа 2011

Единственный обработчик исключений, который, как я вижу, может дать эти результаты, находится в блоке «Это работает с IE».Единственный индекс, на который ссылается этот блок, это Files [0].

Я предлагаю добавить catch (Exception ex) к первой попытке / catch, чтобы определить, почему код, работающий с Safari, не работает с IE.Следует также отметить, что вы читаете поток для всех браузеров, а затем пытаетесь перечитать поток только для IE.Для этого потребуется сброс потока в положение 0.

Проверьте, работает ли этот серверный скрипт со всеми браузерами:

using System;
using System.Web;
using System.IO;
public class Upload : IHttpHandler 
{   
    public void ProcessRequest(HttpContext context) 
    {   
        string path = HttpContext.Current.Server.MapPath("/client/vault/" 
            + Helpers.CurrentClientHash(context.Session["SessionHash"].ToString()) 
            + "/users/" + context.Session["SessionHash"].ToString() 
            + "/");

        HttpPostedFile oFile = 
                    context.Request.Files[context.Request.Headers["X-File-Name"]]; 

        if (!Directory.Exists(path)) Directory.CreateDirectory(path);       
        oFile.SaveAs(path + oFile.FileName);     

        context.Response.Write("1");   
    }   
    public bool IsReusable 
    {      
        get { return true; }   
    }
}
...