值文件上传 - 适用于 Chrome,但不适用于 IE,Image img = Image.FromStream(Request.InputStream)

发布于 2024-10-06 19:11:43 字数 6376 浏览 0 评论 0原文

我正在使用 Valum 上传的稍微修改版本 [github 链接],我已经修改了它上传到数据库,但尚未修改用于将文件作为输入流放入请求的 javascript。

以下代码行在 IE 8 中失败,但已确认在 Chrome 中可以工作。

using (Image imgInput = Image.FromStream(Request.InputStream))

收到的错误是“参数无效”。使用的输入流似乎存在问题,但它存在/有数据(不确定如何验证数据是否良好)。

有人有任何想法或者我可以提供更多详细信息吗?相同的图像能够在 Chrome 中使用并正确上传。

页面

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <h2>Upload-Pictures</h2>
    <div id="file-uploader">
        <noscript>
            <p>Please enable JavaScript to use file uploader.</p>
         </noscript>
    </div>
    <script src="/Scripts/fileuploader.js" type="text/javascript"></script>
    <script type="text/javascript">
        function createUploader() {
            var uploader = new qq.FileUploader({
                element: document.getElementById('file-uploader'),
                action: '/Admin/FileUpload/' + <%= Model.PropertyId %>,
                debug: true
            });
        }
        window.onload = createUploader;
    </script>
</asp:Content>

控制器

    [AcceptVerbs(HttpVerbs.Post)]
    public JsonResult FileUpload(int id)
    {
        try
        {
            byte[] newImageByteArray = GetByteArrayForResizedImage(350, Request.InputStream);
            byte[] thumbnailByteArray = GetByteArrayForResizedImage(150, Request.InputStream);

           //Add to DB
        }
        catch (Exception ex)
        {
            // This is where the exception is caught
            return Json(new { success = false, message = ex.Message }, "application/json");
        }

        return Json(new { success = true }, "application/json");
    }

    private static byte[] GetByteArrayForResizedImage(int imageSize, Stream inputStream)
    {
        byte[] imageByteArray;

        // For some reason in IE the inputStream here is causing it to crash
        using (Image imgInput = Image.FromStream(inputStream))
        {
           //Image processing
        }

        return imageByteArray;
    }

fileuploader.js - qq.FileUploader

/**
 * Class that creates upload widget with drag-and-drop and file list
 * @inherits qq.FileUploaderBasic
 */
qq.FileUploader = function(o){
    // call parent constructor
    qq.FileUploaderBasic.apply(this, arguments);

    // additional options    
    qq.extend(this._options, {
        element: null,
        // if set, will be used instead of qq-upload-list in template
        listElement: null,

        template: '<div class="qq-uploader">' + 
                '<div class="qq-upload-drop-area"><span>Drop files here to upload</span></div>' +
                '<div class="qq-upload-button">Upload a file</div>' +
                '<ul class="qq-upload-list"></ul>' + 
             '</div>',

        // template for one item in file list
        fileTemplate: '<li>' +
                '<span class="qq-upload-file"></span>' +
            '<span class="qq-upload-spinner"></span>' +
            '<span class="qq-upload-size"></span>' +
            '<a class="qq-upload-cancel" href="#">Cancel</a>' +
            '<span class="qq-upload-failed-text">Failed</span>' +
        '</li>',        

        classes: {
            // used to get elements from templates
            button: 'qq-upload-button',
            drop: 'qq-upload-drop-area',
            dropActive: 'qq-upload-drop-area-active',
            list: 'qq-upload-list',

            file: 'qq-upload-file',
            spinner: 'qq-upload-spinner',
            size: 'qq-upload-size',
            cancel: 'qq-upload-cancel',

            // added to list item when upload completes
            // used in css to hide progress spinner
            success: 'qq-upload-success',
            fail: 'qq-upload-fail'
        }
    });
    // overwrite options with user supplied    
    qq.extend(this._options, o);       

    this._element = this._options.element;
    this._element.innerHTML = this._options.template;        
    this._listElement = this._options.listElement || this._find(this._element, 'list');

    this._classes = this._options.classes;

    this._button = this._createUploadButton(this._find(this._element, 'button'));        

    this._bindCancelEvent();
    this._setupDragDrop();
};

fileuploader.js - qq.FileUploaderBasic

/**
 * Creates upload button, validates upload, but doesn't create file list or dd. 
 */
qq.FileUploaderBasic = function(o){
    this._options = {
        // set to true to see the server response
        debug: false,
        action: '/server/upload',
        params: {},
        button: null,
        multiple: true,
        maxConnections: 3,
        // validation        
        allowedExtensions: [],               
        sizeLimit: 0,   
        minSizeLimit: 0,                             
        // events
        // return false to cancel submit
        onSubmit: function(id, fileName){},
        onProgress: function(id, fileName, loaded, total){},
        onComplete: function(id, fileName, responseJSON){},
        onCancel: function(id, fileName){},
        // messages                
        messages: {
            typeError: "{file} has invalid extension. Only {extensions} are allowed.",
            sizeError: "{file} is too large, maximum file size is {sizeLimit}.",
            minSizeError: "{file} is too small, minimum file size is {minSizeLimit}.",
            emptyError: "{file} is empty, please select files again without it.",
            onLeave: "The files are being uploaded, if you leave now the upload will be cancelled."            
        },
        showMessage: function(message){
            alert(message);
        }               
    };
    qq.extend(this._options, o);

    // number of files being uploaded
    this._filesInProgress = 0;
    this._handler = this._createUploadHandler(); 

    if (this._options.button){ 
        this._button = this._createUploadButton(this._options.button);
    }

    this._preventLeaveInProgress();         
};

I'm using a slightly modified version of Valum's upload [github link], I've modified it to upload to a database but haven't modified the javascript that it is using to get the file into the Request as an InputStream.

The following line of code is failing in IE 8 but is confirmed to work in Chrome.

using (Image imgInput = Image.FromStream(Request.InputStream))

The error received is "Parameter not valid". It appears to be having an issue with the Input Stream being used but it exists/has data (not sure how to validate if the data is good or not).

Anyone have any ideas or are there more details I can include? The same image is able to be used in Chrome and is uploaded appropriately.

Page

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <h2>Upload-Pictures</h2>
    <div id="file-uploader">
        <noscript>
            <p>Please enable JavaScript to use file uploader.</p>
         </noscript>
    </div>
    <script src="/Scripts/fileuploader.js" type="text/javascript"></script>
    <script type="text/javascript">
        function createUploader() {
            var uploader = new qq.FileUploader({
                element: document.getElementById('file-uploader'),
                action: '/Admin/FileUpload/' + <%= Model.PropertyId %>,
                debug: true
            });
        }
        window.onload = createUploader;
    </script>
</asp:Content>

Controller

    [AcceptVerbs(HttpVerbs.Post)]
    public JsonResult FileUpload(int id)
    {
        try
        {
            byte[] newImageByteArray = GetByteArrayForResizedImage(350, Request.InputStream);
            byte[] thumbnailByteArray = GetByteArrayForResizedImage(150, Request.InputStream);

           //Add to DB
        }
        catch (Exception ex)
        {
            // This is where the exception is caught
            return Json(new { success = false, message = ex.Message }, "application/json");
        }

        return Json(new { success = true }, "application/json");
    }

    private static byte[] GetByteArrayForResizedImage(int imageSize, Stream inputStream)
    {
        byte[] imageByteArray;

        // For some reason in IE the inputStream here is causing it to crash
        using (Image imgInput = Image.FromStream(inputStream))
        {
           //Image processing
        }

        return imageByteArray;
    }

fileuploader.js - qq.FileUploader

/**
 * Class that creates upload widget with drag-and-drop and file list
 * @inherits qq.FileUploaderBasic
 */
qq.FileUploader = function(o){
    // call parent constructor
    qq.FileUploaderBasic.apply(this, arguments);

    // additional options    
    qq.extend(this._options, {
        element: null,
        // if set, will be used instead of qq-upload-list in template
        listElement: null,

        template: '<div class="qq-uploader">' + 
                '<div class="qq-upload-drop-area"><span>Drop files here to upload</span></div>' +
                '<div class="qq-upload-button">Upload a file</div>' +
                '<ul class="qq-upload-list"></ul>' + 
             '</div>',

        // template for one item in file list
        fileTemplate: '<li>' +
                '<span class="qq-upload-file"></span>' +
            '<span class="qq-upload-spinner"></span>' +
            '<span class="qq-upload-size"></span>' +
            '<a class="qq-upload-cancel" href="#">Cancel</a>' +
            '<span class="qq-upload-failed-text">Failed</span>' +
        '</li>',        

        classes: {
            // used to get elements from templates
            button: 'qq-upload-button',
            drop: 'qq-upload-drop-area',
            dropActive: 'qq-upload-drop-area-active',
            list: 'qq-upload-list',

            file: 'qq-upload-file',
            spinner: 'qq-upload-spinner',
            size: 'qq-upload-size',
            cancel: 'qq-upload-cancel',

            // added to list item when upload completes
            // used in css to hide progress spinner
            success: 'qq-upload-success',
            fail: 'qq-upload-fail'
        }
    });
    // overwrite options with user supplied    
    qq.extend(this._options, o);       

    this._element = this._options.element;
    this._element.innerHTML = this._options.template;        
    this._listElement = this._options.listElement || this._find(this._element, 'list');

    this._classes = this._options.classes;

    this._button = this._createUploadButton(this._find(this._element, 'button'));        

    this._bindCancelEvent();
    this._setupDragDrop();
};

fileuploader.js - qq.FileUploaderBasic

/**
 * Creates upload button, validates upload, but doesn't create file list or dd. 
 */
qq.FileUploaderBasic = function(o){
    this._options = {
        // set to true to see the server response
        debug: false,
        action: '/server/upload',
        params: {},
        button: null,
        multiple: true,
        maxConnections: 3,
        // validation        
        allowedExtensions: [],               
        sizeLimit: 0,   
        minSizeLimit: 0,                             
        // events
        // return false to cancel submit
        onSubmit: function(id, fileName){},
        onProgress: function(id, fileName, loaded, total){},
        onComplete: function(id, fileName, responseJSON){},
        onCancel: function(id, fileName){},
        // messages                
        messages: {
            typeError: "{file} has invalid extension. Only {extensions} are allowed.",
            sizeError: "{file} is too large, maximum file size is {sizeLimit}.",
            minSizeError: "{file} is too small, minimum file size is {minSizeLimit}.",
            emptyError: "{file} is empty, please select files again without it.",
            onLeave: "The files are being uploaded, if you leave now the upload will be cancelled."            
        },
        showMessage: function(message){
            alert(message);
        }               
    };
    qq.extend(this._options, o);

    // number of files being uploaded
    this._filesInProgress = 0;
    this._handler = this._createUploadHandler(); 

    if (this._options.button){ 
        this._button = this._createUploadButton(this._options.button);
    }

    this._preventLeaveInProgress();         
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

诗笺 2024-10-13 19:11:43

事实证明,当使用 IE 作为浏览器时,Request 中没有输入流。最终通过将代码从 Files 数组中拉出来修复代码,如下所示:

if (String.IsNullOrEmpty(Request["qqfile"]))
{ 
    //This works with IE
    HttpPostedFileBase httpPostedFileBase = Request.Files[0] as HttpPostedFileBase;
    byte[] newImageByteArray = GetByteArrayForResizedImage(350, httpPostedFileBase.InputStream);
    byte[] thumbnailByteArray = GetByteArrayForResizedImage(150, httpPostedFileBase.InputStream);

    //Do stuff here

    return Json(new { success = true }, "text/html");
}
else
{
    byte[] newImageByteArray = GetByteArrayForResizedImage(350, Request.InputStream);
    byte[] thumbnailByteArray = GetByteArrayForResizedImage(150, Request.InputStream);

    //Do stuff here

    return Json(new { success = true }, "application/json");
}

Turns out that there is not an input stream in the Request when using IE as your browser. Ended up fixing the code by pulling it out of the Files array like this:

if (String.IsNullOrEmpty(Request["qqfile"]))
{ 
    //This works with IE
    HttpPostedFileBase httpPostedFileBase = Request.Files[0] as HttpPostedFileBase;
    byte[] newImageByteArray = GetByteArrayForResizedImage(350, httpPostedFileBase.InputStream);
    byte[] thumbnailByteArray = GetByteArrayForResizedImage(150, httpPostedFileBase.InputStream);

    //Do stuff here

    return Json(new { success = true }, "text/html");
}
else
{
    byte[] newImageByteArray = GetByteArrayForResizedImage(350, Request.InputStream);
    byte[] thumbnailByteArray = GetByteArrayForResizedImage(150, Request.InputStream);

    //Do stuff here

    return Json(new { success = true }, "application/json");
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文