Asp.net asmx Web服务无法使用FineUploader文件上载返回JSON

Asp.net asmx Web服务无法使用FineUploader文件上载返回JSON,asp.net,ajax,json,web-services,jquery,Asp.net,Ajax,Json,Web Services,Jquery,我知道在这个问题上有很多类似于我的问题,但这些问题并不能解决我的问题。我知道web服务自然地将我的对象解析为json作为框架的一部分。我已经手动将请求头Accept设置为“application/json,text/javascript,/;q=0.01'。我已将添加到我的web服务中 很明显,我的web服务使用文本/普通响应响应文件上载请求头,而解析我的简单FineUploaderResponse对象失败。请记住,对同一web服务的常规jQueryAjax调用可以正常工作。我宁愿不使用Web

我知道在这个问题上有很多类似于我的问题,但这些问题并不能解决我的问题。我知道web服务自然地将我的对象解析为json作为框架的一部分。我已经手动将请求头Accept设置为“application/json,text/javascript,/;q=0.01'。我已将
添加到我的web服务中

很明显,我的web服务使用文本/普通响应响应文件上载请求头,而解析我的简单FineUploaderResponse对象失败。请记住,对同一web服务的常规jQueryAjax调用可以正常工作。我宁愿不使用Web API或通用处理程序来代替我的Web,因为多个网站依赖于我的框架,并且期望使用此标准

提前谢谢

守则:

Public Class FineUploaderResponse
        Property Success As Boolean
    End Class

 <WebMethod(EnableSession:=True)> _
<ScriptMethod(ResponseFormat:=ResponseFormat.Json)> _
Public Function UploadPhotos()
    'next three lines are pointless, didn't help
    'HttpContext.Current.Response.Clear()
    'HttpContext.Current.Response.ContentType = "application/json"
    'HttpContext.Current.Response.Charset = "utf-8"

    Dim response As New FineUploaderResponse()
    response.Success = True

    Return response

End Function
标准jquery请求头是

POST http://localhost:3066/Services/PhotosService.asmx/UploadPhotos HTTP/1.1
Host: localhost:3066
Proxy-Connection: keep-alive
Content-Length: 0
Cache-Control: no-cache
Pragma: no-cache
Origin: http://localhost:3066
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31
Content-Type: application/json; charset=utf-8
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
Referer: http://localhost:3066/Test.aspx
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
但我使用的是FineUploader,它发布的是一种内容类型:多部分/表单数据;请注意,尽管jQuery AJAX和FineUploader请求的Accept标头是相同的:

POST http://localhost:3066/Services/PhotosService.asmx/UploadPhotos HTTP/1.1
Host: localhost:3066
Proxy-Connection: keep-alive
Content-Length: 110634
Cache-Control: no-cache
Pragma: no-cache
Origin: http://localhost:3066
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary449tHPTKEpuO5jOR
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
Referer: http://localhost:3066/Sellers/photos/?pid=37344
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
来自标准Jquery ajax调用的web服务响应为:

HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Wed, 17 Apr 2013 00:12:21 GMT
X-AspNet-Version: 4.0.30319
Cache-Control: private, max-age=0
Content-Type: application/json; charset=utf-8
Content-Length: 22
Connection: Close
FineUploader post文件请求的web服务响应为:

HTTP/1.1 500 Internal Server Error
Server: ASP.NET Development Server/10.0.0.0
Date: Wed, 17 Apr 2013 00:18:26 GMT
X-AspNet-Version: 4.0.30319
Cache-Control: private
Content-Type: text/plain; charset=utf-8
Content-Length: 1936
Connection: Close
内部服务器500错误消息详细信息如下:

System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException: The type Kazork.AppCode.PhotosService+FineUploaderResponse was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.
   at System.Xml.Serialization.XmlSerializationWriter.WriteTypedPrimitive(String name, String ns, Object o, Boolean xsiType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write1_Object(String n, String ns, Object o, Boolean isNullable, Boolean needType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write3_anyType(Object o)
   at Microsoft.Xml.Serialization.GeneratedAssembly.ObjectSerializer1.Serialize(Object objectToSerialize, XmlSerializationWriter writer)
   at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
   --- End of inner exception stack trace ---
   at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
   at System.Xml.Serialization.XmlSerializer.Serialize(TextWriter textWriter, Object o, XmlSerializerNamespaces namespaces)
   at System.Web.Services.Protocols.XmlReturnWriter.Write(HttpResponse response, Stream outputStream, Object returnValue)
   at System.Web.Services.Protocols.HttpServerProtocol.WriteReturns(Object[] returnValues, Stream outputStream)
   at System.Web.Services.Protocols.WebServiceHandler.WriteReturns(Object[] returnValues)
   at System.Web.Services.Protocols.WebServiceHandler.Invoke()
如果你好奇的话,这里是我的FineUploader电话:

 var uploader = new qq.FineUploader({
            element: document.getElementById('bootstrapped-fine-uploader'),
            request: {
                endpoint: "/Services/PhotosService.asmx/UploadPhotos",
                forceMultipart: true,
                params: { propertyId:<%=PropertyId %>},
                customHeaders: { Accept: 'application/json, text/javascript, */*; q=0.01' }
            },
            text: {
                uploadButton: '<i class="icon-upload icon-white"></i>Upload nice images.'
            },
            template: '<div class="qq-uploader">' +
                        '<pre class="qq-upload-drop-area"><span>{dragZoneText}</span></pre>' +
                        '<div class="qq-upload-button btn btn-success" style="width: auto;">{uploadButtonText}</div>' +
                        '<span class="qq-drop-processing"><span>{dropProcessingText}</span><span class="qq-drop-processing-spinner"></span></span>' +
                      '</div>' +
                      '<ul class="qq-upload-list" style="margin-top: 10px; text-align: center;"></ul>' +
                      '',
            classes: {
                success: 'alert alert-success',
                fail: 'alert alert-error'
            },
            debug: false,
            callbacks: {
//                onComplete: function (id, fileName, responseJson) {
//                    $.when(loadThumbs()).done(function () {
//                        $(".qq-upload-list > .alert-success").remove();
//                    });
//                    toastr.success("Success!");
//                },
                 onComplete: function(id, fileName, responseJSON) {
                      if (responseJSON.success) {
                        $('#file-' + id).removeClass('alert-info')
                                        .addClass('alert-success')
                                        .html('<i class="icon-ok"></i> ' +
                                              'Successfully saved ' +
                                              '“' + fileName + '”' +
                                              '<br><img src="/images/message_ok.png" alt="' + fileName + '">');

                          $.when(loadThumbs()).done(function () {
                                $(".qq-upload-list > .alert-success").remove();
                            });
                          toastr.success("Success!");
                      } else {
                        $('#file-' + id).removeClass('alert-info')
                                        .addClass('alert-error')
                                        .html('<i class="icon-exclamation-sign"></i> ' +
                                              'Error with ' +
                                              '“' + fileName + '”: ' +
                                              responseJSON.error);
                      }
                },
                onError: function (id, fileName, errorReason) {
                    toastr.error("Failed! Try again.");
                }
            }
        });
var uploader=new qq.FineUploader({
元素:document.getElementById('bootstrapped-fine-uploader'),
请求:{
端点:“/Services/photoservice.asmx/UploadPhotos”,
forceMultipart:true,
参数:{propertyId:},
customHeaders:{Accept:'application/json,text/javascript,*/*;q=0.01'}
},
正文:{
uploadButton:“上传漂亮的图片。”
},
模板:“”+
“{dragZoneText}”+
“{uploadButtonText}”+
“{dropProcessingText}”+
'' +
“
    ”+ '', 课程:{ 成功:“警报成功”, 失败:“警报错误” }, 调试:错误, 回调:{ //onComplete:函数(id、文件名、responseJson){ //$.when(loadThumbs()).done(函数(){ //$(“.qq上传列表>.alert success”).remove(); // }); //成功(“成功!”); // }, onComplete:函数(id、文件名、responseJSON){ if(responseJSON.success){ $('#文件-'+id).removeClass('alert-info')) .addClass(“警报成功”) .html(“”+ “已成功保存”+ “'”+文件名+“'+ “
    ”); $.when(loadThumbs()).done(函数(){ $(“.qq上传列表>.alert success”).remove(); }); 成功(“成功!”); }否则{ $('#文件-'+id).removeClass('alert-info')) .addClass('alert-error') .html(“”+ '错误与'+ “'+fileName+'”:'+ 响应(错误); } }, onError:函数(id、文件名、错误原因){ toastr.error(“失败!重试”); } } });
    好的,很容易修复,但令人沮丧的是,web服务花费了我很多时间来维护一个当代的web应用程序。但我现在不需要迁移到Web API,主要是因为我的Web应用程序依赖于会话(您可以将会话引入Web API,但这显然不是RESTful)

    因此,我用自己的格式化JSON响应替换了FineUploaderResponse类:

    <WebMethod(EnableSession:=True)> _
    <ScriptMethod(ResponseFormat:=ResponseFormat.Json)> _
    Public Sub UploadPhotos()
    
        Context.Response.Write(New ResultData().GetResultDataJSON("success", "true"))
    
    End Sub
    
    
        Public Function GetResultDataJSON(key As String, value As String) As String
            Dim oBuilder As StringBuilder = New StringBuilder()
            oBuilder.Append("{")
            oBuilder.AppendFormat("""{0}"" : {1}", key, value)
            oBuilder.Append("}")
            Return oBuilder.ToString()
        End Function
    
    _
    _
    公共子上传照片()
    Write(New ResultData().GetResultDataJSON(“success”,“true”))
    端接头
    公共函数GetResultDataJSON(键作为字符串,值作为字符串)作为字符串
    作为StringBuilder的尺寸对象生成器=新StringBuilder()
    oBuilder.Append(“{”)
    AppendFormat(“{0}”:{1}”,键,值)
    oBuilder.Append(“}”)
    返回oBuilder.ToString()
    端函数
    
    下面是我的FineUploader Javascript:

    /*=================================================*/
    //fineUploaderInitialize
    /*=================================================*/
        function createUploader() {
            var uploader = new qq.FineUploader({
                element: document.getElementById('bootstrapped-fine-uploader'),
                request: {
                    endpoint: "/Services/PhotosService.asmx/UploadPhotos",
                    forceMultipart: true,
                    params: { propertyId:$('#hiddenPropertyIdUploadPhotosUserControl').val()},
                    customHeaders: { Accept: 'application/json, text/javascript, */*; q=0.01' },
                    allowedExtensions: ['gif', 'jpeg', 'jpg', 'png'],
                },
                text: {
                    uploadButton: 'Drag & drop photos into this area or CLICK HERE to upload photos'
                },
                template: '<div class="qq-uploader text-center" style="height:70px;background-color:white;border-radius:6px;">' +
                            '<div class="qq-upload-button btn btn-success col-lg-12">{uploadButtonText}</div>' +
                            '<span class="qq-drop-processing"><span>{dropProcessingText}</span><span class="qq-drop-processing-spinner"></span></span>' +
                            '<pre class="qq-upload-drop-area"><span>{dragZoneText}</span></pre>' +
                          '</div>' +
                          '<ul class="qq-upload-list" style="margin-top: 10px; text-align: center;"></ul>' +
                          '',
                classes: {
                    success: 'alert alert-success',
                    fail: 'alert alert-error'
                },
                debug: false,
                callbacks: {
                    onComplete: function(id, fileName, responseJSON) {
                        if (responseJSON.success) {
                            $('#file-' + id).removeClass('alert-info')
                                            .addClass('alert-success')
                                            .html('<i class="glyphicon glyphicon-ok"></i> ' +
                                                  'Successfully saved ' +
                                                  '“' + fileName + '”' +
                                                  '<br><img src="/images/message_ok.png" alt="' + fileName + '">');
                            $.when(loadThumbs()).done(function () {
                                $(".qq-upload-list > .alert-success").remove();
                            });
                            toastr.success("Success!");
                        } else {
                            $('#file-' + id).removeClass('alert-info')
                                            .addClass('alert-error')
                                            .html('<i class="glyphicon glyphicon-exclamation-sign"></i> ' +
                                                  'Error with ' +
                                                  '“' + fileName + '”: ' +
                                                  responseJSON.error);
                        }
                    },
                    onError: function (id, fileName, errorReason) {
                        if(errorReason == 'XHR returned response code 0'){
                            toastr.error('File Size Cannot Exceed 20 Megabytes');
                        }else{
                            toastr.error(errorReason);
                        }
                    }
                }
            });
        }
    /*=================================================*/
    
    /*=================================================*/
    //精细上载初始化
    /*=================================================*/
    函数createUploader(){
    var uploader=new qq.FineUploader({
    元素:document.getElementById('bootstrapped-fine-uploader'),
    请求:{
    端点:“/Services/photoservice.asmx/UploadPhotos”,
    forceMultipart:true,
    参数:{propertyId:$('#hiddenPropertyIdUploadPhotosUserControl').val(),
    customHeaders:{Accept:'application/json,text/javascript,*/*;q=0.01'},
    允许的扩展名:['gif','jpeg','jpg','png'],
    },
    正文:{
    uploadButton:'将照片拖放到此区域或单击此处上载照片'
    },
    模板:“”+
    “{uploadButtonText}”+
    “{dropProcessingText}”+
    “{dragZoneText}”+
    '' +
    “
      /*=================================================*/ //fineUploaderInitialize /*=================================================*/ function createUploader() { var uploader = new qq.FineUploader({ element: document.getElementById('bootstrapped-fine-uploader'), request: { endpoint: "/Services/PhotosService.asmx/UploadPhotos", forceMultipart: true, params: { propertyId:$('#hiddenPropertyIdUploadPhotosUserControl').val()}, customHeaders: { Accept: 'application/json, text/javascript, */*; q=0.01' }, allowedExtensions: ['gif', 'jpeg', 'jpg', 'png'], }, text: { uploadButton: 'Drag & drop photos into this area or CLICK HERE to upload photos' }, template: '<div class="qq-uploader text-center" style="height:70px;background-color:white;border-radius:6px;">' + '<div class="qq-upload-button btn btn-success col-lg-12">{uploadButtonText}</div>' + '<span class="qq-drop-processing"><span>{dropProcessingText}</span><span class="qq-drop-processing-spinner"></span></span>' + '<pre class="qq-upload-drop-area"><span>{dragZoneText}</span></pre>' + '</div>' + '<ul class="qq-upload-list" style="margin-top: 10px; text-align: center;"></ul>' + '', classes: { success: 'alert alert-success', fail: 'alert alert-error' }, debug: false, callbacks: { onComplete: function(id, fileName, responseJSON) { if (responseJSON.success) { $('#file-' + id).removeClass('alert-info') .addClass('alert-success') .html('<i class="glyphicon glyphicon-ok"></i> ' + 'Successfully saved ' + '“' + fileName + '”' + '<br><img src="/images/message_ok.png" alt="' + fileName + '">'); $.when(loadThumbs()).done(function () { $(".qq-upload-list > .alert-success").remove(); }); toastr.success("Success!"); } else { $('#file-' + id).removeClass('alert-info') .addClass('alert-error') .html('<i class="glyphicon glyphicon-exclamation-sign"></i> ' + 'Error with ' + '“' + fileName + '”: ' + responseJSON.error); } }, onError: function (id, fileName, errorReason) { if(errorReason == 'XHR returned response code 0'){ toastr.error('File Size Cannot Exceed 20 Megabytes'); }else{ toastr.error(errorReason); } } } }); } /*=================================================*/