服务器返回有效的json和200,但抛出了错误函数

时间:2012-12-15 01:15:31

标签: asp.net ajax

好的,所以由于某种原因,即使服务器使用有效的json返回200,我的ajax调用也会一直失败。这是ajax调用:

        $.ajax(
        {
            cache: false,
            type: "GET",
            url: "http://localhost:10590/api/entry",
            dataType: "application/json; charset=utf-8",
            success: function (result) {
                alert('HIT');
            },
            error: function (request, type, errorThrown) {
                alert('Fail' + type + ':' + errorThrown);
            }
        });

错误功能显示空白。类型说“错误”,但之后没有。我想弄清楚为什么会发生这种情况???

通过fiddler验证,这是从服务器返回的json字符串:

{
  "EntryId":0,
  "EntryDate":"2012-12-14T18:10:48.2275967-07:00",
  "BodyWeight":207.00,
  "Bmi":0.0,
  "Fat":0.0,
  "Visceral":0.0,
  "MuscleMass":0.0
}

http://jsonlint.com/同意这是有效的json。

更新: 在ajax调用之前添加以下内容使其在IE中工作但不是chrome:

$.support.cors = true;

2 个答案:

答案 0 :(得分:1)

当我从文件系统上的html页面测试对Web服务器的ajax调用时,我遇到了类似的问题。我想这算作'跨域'ajax。我有完全相同的症状。 Wireshark从Web服务器上得到了非常好的响应,但是我收到了一个没有数据的错误事件。

一旦我将HTML文件移动到Web服务器 - 以便我的页面(ajax客户端)和ajax Web服务位于同一个域中,它们就开始工作了。

但是,如果提交ajax的网页是从http://localhost:10590/提供的,那么这不适用,而且您遇到了其他问题。

答案 1 :(得分:0)

我最终使用的解决方案是从服务器请求'jsonp'。为了让我的服务器返回jsonp,我不得不创建一个自定义格式化程序。我很难找到一个格式化程序,因为每个帖子都提到了Thinktecture,它不会为我编译。所以这就是我最终的结果:

using System;
using System.IO;
using System.Net;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Web;
using System.Net.Http;
using Newtonsoft.Json.Converters;

namespace MyDomain.Common.Web.CustomFormatters
{

    /// <summary>
    /// Handles JsonP requests when requests are fired with text/javascript
    /// </summary>
    public class JsonpFormatter : JsonMediaTypeFormatter
    {

        public JsonpFormatter()
        {
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript"));

            JsonpParameterName = "callback";
        }

        /// <summary>
        ///  Name of the query string parameter to look for
        ///  the jsonp function name
        /// </summary>
        public string JsonpParameterName { get; set; }

        /// <summary>
        /// Captured name of the Jsonp function that the JSON call
        /// is wrapped in. Set in GetPerRequestFormatter Instance
        /// </summary>
        private string JsonpCallbackFunction;


        public override bool CanWriteType(Type type)
        {
            return true;
        }

        /// <summary>
        /// Override this method to capture the Request object
        /// </summary>
        /// <param name="type"></param>
        /// <param name="request"></param>
        /// <param name="mediaType"></param>
        /// <returns></returns>
        public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, System.Net.Http.HttpRequestMessage request, MediaTypeHeaderValue mediaType)
        {
            var formatter = new JsonpFormatter()
            {
                JsonpCallbackFunction = GetJsonCallbackFunction(request)
            };

            // this doesn't work unfortunately
            //formatter.SerializerSettings = GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings;

            // You have to reapply any JSON.NET default serializer Customizations here    
            formatter.SerializerSettings.Converters.Add(new StringEnumConverter());
            formatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;

            return formatter;
        }


        public override Task WriteToStreamAsync(Type type, object value,
                                        Stream stream,
                                        HttpContent content,
                                        TransportContext transportContext)
        {
            if (string.IsNullOrEmpty(JsonpCallbackFunction))
                return base.WriteToStreamAsync(type, value, stream, content, transportContext);

            StreamWriter writer = null;

            // write the pre-amble
            try
            {
                writer = new StreamWriter(stream);
                writer.Write(JsonpCallbackFunction + "(");
                writer.Flush();
            }
            catch (Exception ex)
            {
                try
                {
                    if (writer != null)
                        writer.Dispose();
                }
                catch { }

                var tcs = new TaskCompletionSource<object>();
                tcs.SetException(ex);
                return tcs.Task;
            }

            return base.WriteToStreamAsync(type, value, stream, content, transportContext)
                       .ContinueWith(innerTask =>
                       {
                           if (innerTask.Status == TaskStatus.RanToCompletion)
                           {
                               writer.Write(")");
                               writer.Flush();
                           }

                       }, TaskContinuationOptions.ExecuteSynchronously)
                        .ContinueWith(innerTask =>
                        {
                            writer.Dispose();
                            return innerTask;

                        }, TaskContinuationOptions.ExecuteSynchronously)
                        .Unwrap();
        }

        /// <summary>
        /// Retrieves the Jsonp Callback function
        /// from the query string
        /// </summary>
        /// <returns></returns>
        private string GetJsonCallbackFunction(HttpRequestMessage request)
        {
            if (request.Method != HttpMethod.Get)
                return null;

            var query = HttpUtility.ParseQueryString(request.RequestUri.Query);
            var queryVal = query[this.JsonpParameterName];

            if (string.IsNullOrEmpty(queryVal))
                return null;

            return queryVal;
        }
    }
}