如何解决此 WCF 异常?

问题描述 投票:0回答:6

我在使用 WCF 服务时遇到问题。返回类型是一种半复杂类型,它引用各种基本类型和每个类型继承自的基本接口。

在我的调试中,序列化消息的总字节大小远低于默认的 65535 字节阈值。尽管如此,我已将 maxReceivedMessageSize 属性增加到 1000000,但问题仍然存在。

WCF服务定义如下:

[ServiceContract]
public interface ILoggingService
{
    [OperationContract]
    NotesInfo ListNotes(NotesQueryOptions options);
}

以下是 NotesInfo 返回对象的定义:

[DataContract]
public class NotesInfo
{
    [DataMember] public List<TokenizedNote> Notes { get; set; }
    [DataMember] public Dictionary<long, User> Users { get; set; }
    [DataMember] public Dictionary<long, NoteCategory> NoteCategories { get; set; }
    [DataMember] public Dictionary<string, Dictionary<long, IIdentifiable<long>>> EntitiesByToken { get; set; }
}

当我尝试调用该服务时,抛出以下异常:

服务器未提供 有意义的回复;这可能是由于 由于合同不匹配、过早 会话关闭或内部服务器 错误。描述:未处理 期间发生异常 执行当前的网络请求。 请查看堆栈跟踪以了解更多信息 有关错误及其位置的信息 它起源于代码。

异常详细信息: System.ServiceModel.CommunicationException: 服务器没有提供 有意义的回复;这可能是由于 由于合同不匹配、过早 会话关闭或内部服务器 错误。

来源错误:

Line 242:
Line 243: public AxeFrog.Mobile.NotesInfo ListNotes(AxeFrog.Mobile.NotesQueryOptions options) {
Line 244:            return base.Channel.ListNotes(options);
Line 245:        }
Line 246:    }

源文件: C:\用户\内森\工作\内部 项目\AxeFrog 系统\源\Trunk\AxeFrog.Mobile.WebInterface\Service 参考文献\LoggingServiceReference\Reference.cs 线路:244

以下是涉及的其他实体的代码:

public interface IIdentifiable<TID>
{
    TID ID { get; set; }
}

[DataContract]
public class Note : IIdentifiable<long>
{
    [DataMember] public long ID { get; set; }
    [DataMember] public DateTime DateStamp { get; set; }
    [DataMember] public long? UserID { get; set; }
    [DataMember] public long NoteCategoryID { get; set; }
    [DataMember] public NoteType NoteType { get; set; }
    [DataMember] public string Message { get; set; }
}

public enum NoteType
{
    Information = 0,
    Warning = 10,
    Failure = 20
}

[DataContract]
public class NoteCategory : IIdentifiable<long>
{
    [DataMember] public long ID { get; set; }
    [DataMember] public string Name { get; set; }
}

[DataContract]
public class NoteEntityType : IIdentifiable<long>
{
    [DataMember] public long ID { get; set; }
    [DataMember] public Type TypeName { get; set; }
}

[DataContract]
public class TokenizedNote
{
    [DataMember] public Note Note { get; set; }
    [DataMember] public List<NoteSegment> NoteSegments { get; set; }
}

public abstract class NoteSegment
{
    public abstract string Render(INoteRenderer renderer, Dictionary<string, Dictionary<long, IIdentifiable<long>>> entitiesByToken);
}

[DataContract]
public class NoteTextSegment : NoteSegment
{
    [DataMember]
    public string Text { get; set; }
}

[DataContract]
public class NoteEntitySegment : NoteSegment
{
    [DataMember] public long EntityID { get; set; }
    [DataMember] public string Token { get; set; }
}

请注意,为了便于阅读,我已从 NoteSegment 的抽象实现中删除了 Render() 重写。

以下是来自调试器的一些信息,以便您可以查看返回的内容:

alt text alt text

任何对我在这里可能做错的事情的见解将不胜感激。谷歌搜索几乎找不到有用的答案。

c# wcf
6个回答
0
投票

您在客户端显示异常;当您在服务器上附加调试器(或打开日志记录)时会发生什么,在那里看到任何有用的东西?


0
投票

这可能是由于消息太长造成的。您应该尝试通过编辑您的 app.config 来更改限制,如下所示:

<binding name="WebBinding" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
  <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
    maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />

0
投票

您的服务器是否需要花费太长的时间来整理响应?客户端默认的“sendTimeout”仅为 60 秒 - 您可以尝试将其增加到更高的值:

<binding name="TweakedBinding" sendTimeout="120" />

您的客户端配置是什么样的?您使用什么绑定?什么安全设置?

马克

更新:
您能否将服务调试行为添加到您的服务中,以便在出现问题时在客户端获得更多调试和错误信息??

<behaviors>
  <serviceBehavior>
    <behavior name="YourBehaviorName">
       <serviceDebug includeExceptionDetailInFaults="True" />
    </behavior>
  </serviceBehavior>
</behaviors>

0
投票

这个问题已经很老了,但我会把它扔在那里以防其他人发现它有用。我猜测这里发生的事情是从 NoteSegment 继承 - 您需要使用 KnownType 属性来告诉 TokenizedNote 对象,它在反序列化时可以期望 NoteTextSegment 和 NoteEntitySegment (因为默认情况下它只期望 NoteSegment 的实例)。

[DataContract]
[KnownType(typeof(NoteEntitySegment)]
[KnownType(typeof(NoteTextSegment)]
public class TokenizedNote
{
    [DataMember] public Note Note { get; set; }
    [DataMember] public List<NoteSegment> NoteSegments { get; set; }
}

有关详细信息,请参阅此资源:http://msdn.microsoft.com/en-us/library/ms730167(v=vs.110).aspx


0
投票

我也遇到了类似的问题。在花了 2 个小时思考这个问题并试图在网上找到答案之后,我决定遵循使用 System.Runtime.Serialization.DataContractSerializer 在服务器端序列化和反序列化返回值/对象的方法,最后发现我错过了在其中一个 Enum 上添加 EnumMember 属性。

这是帮助我解决问题的代码片段:

      var dataContractSerializer = new System.Runtime.Serialization.DataContractSerializer(typeof(MyObject));
      byte[] serializedBytes;
        using (System.IO.MemoryStream mem1 = new System.IO.MemoryStream())
        {
            dataContractSerializer.WriteObject(mem1, results);
            serializedBytes = mem1.ToArray();
        }

        MyObject deserializedResult;
        using (System.IO.MemoryStream mem2 = new System.IO.MemoryStream(serializedBytes))
        {
            deserializedResult = (MyObject)dataContractSerializer.ReadObject(mem2);
        }

0
投票

打开IIS,选择站点,单击“基本设置”,然后单击“测试设置”。我忽略的是该网站需要有效的凭据及其应用程序池。

© www.soinside.com 2019 - 2024. All rights reserved.