1

我在使用 jQuery AJAX 从“启用 AJAX 的 WCF 服务”中的 WebGet 函数检索数据时遇到问题。服务代码如下图:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Text;

namespace SPA
{
  [ServiceContract(Namespace = "")]
  [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
  public class db
  {
    // To use HTTP GET, add [WebGet] attribute. (Default ResponseFormat is WebMessageFormat.Json)
    // To create an operation that returns XML,
    //     add [WebGet(ResponseFormat=WebMessageFormat.Xml)],
    //     and include the following line in the operation body:
    //         WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml";
    [WebGet]
    [OperationContract]
    public IEnumerable<Geofence> GetGeofences()
    {
      WebOperationContext.Current.OutgoingResponse.ContentType = "text/json";
      var dc = new AtomnetDataContext();
      return dc.Geofences;
    }

    // Add more operations here and mark them with [OperationContract]
  }
}

这是试图调用它的代码:

$(function () {
  $.get("db.svc/GetGeofences", alert);
});

在服务方法代码中放置一个断点表明它确实被调用了。我确认通过将 dc.Geofences.ToArray() 实现为变量(示例中未显示)已成功获取数据。Geofence是 Linq2sql 生成的类型。

将调用转换为显式 ajax 调用$.ajax({ ... });会将错误对象返回给错误函数,但其​​中包含的消息仅说“错误”,这没有什么指导意义。

使用相当于 Firebug 的 IE10 检查网络流量显示调用是“(中止)”。这个问题必须是服务配置,因为调用会试图返回一个值。

似乎有一个序列化异常,然后是一个可能是必然的通信异常。

A first chance exception of type 'System.Runtime.Serialization.SerializationException' 
occurred in System.Runtime.Serialization.dll A first chance exception of type 
'System.ServiceModel.CommunicationException' occurred in System.ServiceModel.Web.dll
4

1 回答 1

0

The root of all the problems was the fact that after adding the badly named entity SiteData to the model, I renamed it to Geofences. If you do this, you get the problems I describe. If you don't, everything's hunky dory.

Another problem that I still face is that when I include other entities that have relationships to SiteData that the designer recognises and implements, this also produces serialisation errors. Manually removing the relationships sorts it out, but I have the strongest feeling you can probably also fix this with a config setting. Anyone know how?

Oh, and you can't pass alert as the success function, passing a native function like this seems to discombobulate jquery. The example on p70 of the O'reilly jQuery Pocket Reference doesn't work. Not with IE10, at any rate.

The serialisation errors are a result of cycles. A bit more digging produced this message:

System.Runtime.Serialization.SerializationException occurred
  HResult=-2146233076
  Message=Object graph for type 'SPA.SiteGroup' contains cycles and cannot be 
  serialized if reference tracking is disabled.
  Source=System.Runtime.Serialization
  StackTrace:
       at System.Runtime.Serialization.XmlObjectSerializerWriteContext.OnHandleReference(XmlWriterDelegator xmlWriter, Object obj, Boolean canContainCyclicReference)
  InnerException: 

The question now is how to enable reference tracking.

This ought to be an attribute of the endpoint behaviour.

<behaviors>
  <endpointBehaviors>
    <behavior name="SPA.dbAspNetAjaxBehavior">
      <enableWebScript />
      <dataContractSerializer 
        preserveObjectReferences="true"
        ignoreExtensionDataObject="false" 
        maxItemsInObjectGraph="99" />
    </behavior>
  </endpointBehaviors>
</behaviors>

Unfortunately, you can't do anything so reasonable because System.ServiceModel.Configuration.DataContractSerializerElement doesn't expose the preserveObjectReferences constructor parameter for the DataContractSerializer.

The conspiracy theorist in me suspects that this is no accident. The Entity Framework team doesn't like Linq2Sql because it embarrasses them by out performing EF by a country mile.

I found another workaround: if you don't want to delete the associations, you can select them and set the Child Property property to False. This inhibits the generation of a child objects collection and then you don't have a circular reference.

于 2013-10-29T06:15:05.870 回答