如何解决此WCF异常?

时间:2009-09-07 12:01:11

标签: c# wcf

我遇到了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; }
}

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

  

服务器没有提供   有意义的答复这可能是造成的   合同不匹配,为时过早   会话关闭或内部服务器   错误。描述:未处理   期间发生了异常   执行当前的Web请求。   请查看堆栈跟踪了解更多信息   有关错误的信息和位置   它起源于代码。

     

异常详细信息:   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:\ Users \用户弥敦道\工作\内部   项目\ AxeFrog   系统\源\干线\ AxeFrog.Mobile.WebInterface \服务   参考\ 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()覆盖。

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

alt text alt text

对此我可能做错的任何见解都将不胜感激。谷歌搜索几乎没有产生有用的答案。

6 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

这可能是由邮件太长造成的。您应该尝试通过编辑app.config来更改限制:

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

答案 2 :(得分:0)

难道你的服务器只是花了太长时间才能把响应放在一起吗?客户端上的默认“sendTimeout”只有60秒 - 您可以尝试将其增加到更高的值:

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

您的客户端配置是什么样的?你使用什么装订?什么安全设置?

马克

<强>更新
你可以将服务调试行为添加到你的服务中,这样当出现问题时你会在客户端获得更多的调试和错误信息吗?

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

答案 3 :(得分: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

答案 4 :(得分:0)

我遇到了类似的问题。在花了2个小时思考并尝试在线找到答案之后,我决定使用System.Runtime.Serialization.DataContractSerializer跟踪方法来对服务器端的返回值/对象进行seralize和反序列化,最后发现我错过了在其中一个枚举上添加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);
        }

答案 5 :(得分:0)

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