1

我知道在这个主题上有很多与我类似的问题,但这些问题并不能解决我的问题。我知道 Web 服务自然地将我的对象解析为 json 作为框架的一部分。我已手动将请求标头标头 Accept 设置为 'application/json, text/javascript, / ; q=0.01'。我已将其添加<ScriptMethod(ResponseFormat:=ResponseFormat.Json)>到我的网络服务中。

很明显,我的 Web 服务正在使用文本/纯文本响应响应文件上传请求标头,并且解析我的简单 FineUploaderResponse 对象失败。请记住,对同一 Web 服务的常规 jQuery AJAX 调用可以正常工作。我不希望使用 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

现在当然,如果我这样做,这个网络服务就可以工作:

  $(document).ready(function () {
            $.ajax(
            {
                url: "/Services/PhotosService.asmx/UploadPhotos",
                type: "POST",
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (data) {
                    console.log(data.d);
                }

            });

        });

标准的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,它正在发布 Content-Type:multipart/form-data; 请注意,尽管 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 发布文件请求的 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.");
                }
            }
        });
4

1 回答 1

1

好吧,很容易解决,但令人沮丧的是,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

这是我的 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);
                    }
                }
            }
        });
    }
/*=================================================*/
于 2013-04-17T17:29:03.153 回答