我使用Visual Studio 2010和MS SQL Server 2005.我是WCF的新手,我正在尝试学习开发小型任务管理应用程序。
目前我有一个内置两个控制台应用程序的解决方案 - WCF服务 - 连接到WCF服务以测试我的代码的客户端
WCF服务使用LINQ to SQL连接到数据库。 我已经实现了一个OperationContract,它将一些内容插入到WCF服务后面的数据库中并且它可以工作。 我已经实现了一个OperationContract,它将WCF服务中的GUID返回给客户端,并且也可以。
当我尝试从WCF服务检索List列表时,它失败并出现以下错误:
“接收到localhost:8000 / TaskerTest / Service / operations的HTTP响应时发生错误。这可能是由于服务端点绑定不使用HTTP协议。这也可能是由于HTTP请求上下文被服务器中止
InnerException:基础连接已关闭:接收时发生意外错误。
我的合同(前两项工作.GetLists是问题):
[ServiceContract(Namespace = "http://Tasker_Server")]
public interface IOperations {
[OperationContract]
string CreateList(string listName, string text);
[OperationContract]
string UpdateList(int idList, string listName, string text);
[OperationContract]
List<ToDoList> GetLists();
}
实施:
public List<ToDoList> GetLists() {
Guid token = OperationContext.Current.IncomingMessageHeaders.GetHeader<Guid>("token", "ns");
int? userID = CheckCache(token);
if (userID != null) {
List<ToDoList> lst = DBAccess.GetListsByUserId(userID.Value);
return lst;
}
else
return null;
}
数据库访问代码:
public static List<ToDoList> GetListsByUserId(int idCredential) {
TaskerModelDataContext tmdc = new TaskerModelDataContext();
List<ToDoList> lists = tmdc.ToDoLists.Where(entry => entry.id_Credential == idCredential).ToList<ToDoList>();
return lists;
}
客户端代码(WCF服务作为服务引用添加到客户端项目中):
TaskerService.LoginClient test2 = new LoginClient();
string username = "usr1", password = "psw1";
test2.ClientCredentials.UserName.UserName = username;
test2.ClientCredentials.UserName.Password = password;
Guid result = Guid.Empty;
try {
result = test2.CheckCredentials(username, password);
Console.WriteLine("Login OK!");
}
catch (Exception e) {
Console.WriteLine(e.Message);
}
TaskerService.OperationsClient client = new OperationsClient();
using(OperationContextScope contextScope = new OperationContextScope(client.InnerChannel)) {
Guid testToken = result; Console.WriteLine(testToken.ToString());
MessageHeader<Guid> mhg = new MessageHeader<Guid>(testToken);
MessageHeader untyped = mhg.GetUntypedHeader("token", "ns");
OperationContext.Current.OutgoingMessageHeaders.Add(untyped);
client.GetLists();
}
client.Close();
客户端因以上异常而失败:client.GetLists();
我可以根据读者的需要提供任何其他详细信息。
更新
我已经开始跟踪
了 <system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="System.ServiceModel"
switchValue="Information, ActivityTracing"
propagateActivity="true">
<listeners>
<add name="sdt"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData= "SdrConfigExample.e2e" />
</listeners>
</source>
</sources>
</system.diagnostics>
然后我在生成的日志上运行Microsoft Service Trace Viewer并收到以下错误:
尝试序列化参数时出错。 InnerException消息是'Type'System.DelegateSerializationHolder + DelegateEntry',数据协定名称为'DelegateSerializationHolder.DelegateEntry:http://schemas.datacontract.org/2004/07/System'不是预期的
我现在已经将[DataContract]添加到我的dbml文件中的“ToDoList”类中,现在我没有收到异常。我在客户端获得了正确的结果数量但是每个类的内容似乎都是空的。
答案 0 :(得分:2)
我的数据库类是使用dbml文件(LINQ to SQL)自动生成的。
我在&#34; TaskerModel.designer.cs&#34;中添加了一个[DataContract()]属性到ToDoList类。 (自动生成的文件)我没有收到异常,但我在客户端检索的类只有每个成员的默认值。
然后我将[DataMember()]属性添加到ToDoList类的所有成员并添加了
[ServiceKnownType(typeof(ToDoList))]
到
[ServiceContract(Namespace = "http://Tasker_Server")]
public interface IOperations {
[OperationContract]
string CreateList(string listName, string text);
[OperationContract]
string UpdateList(int idList, string listName, string text);
[OperationContract]
List<ToDoList> GetLists();
}
现在它有效。不知道是否有更容易的方法,但它现在有效。如果有人知道更好的方法,我会很感激评论。
答案 1 :(得分:2)
在我的情况下,问题是有一个只读属性。添加一个空集();并解决我的问题。
答案 2 :(得分:0)
调用我的WCF restfull服务时遇到了同样的错误。问题似乎是由我作为响应返回的数据类型引起的。
我返回了JSON,我的response-object有一个数据类型为DateTime的变量。当我用字符串替换DateTime时,问题就消失了,并返回了正确的响应。可能它会帮助那些遇到同样问题的人。
替换:
[DataMember]
public DateTime dateFrom {get;set;}
用这个
[DataMember]
public string dateFrom {get;set;}