【发布时间】:2012-12-27 23:07:48
【问题描述】:
好的,我在解决某个特定问题时遇到了很大的困难。通过服务转移对象。从概念上讲,这是有道理的……我认为?根据我的阅读,除非明确定义,否则无法序列化 Generic。
所以我想提供我的例子;我根本无法上班。意思是;我相信还有其他人也遇到了一些困难。当您提供代码时提供帮助;这将起作用并解释它。这样我就可以完全理解这个问题。这将有助于我了解 Windows Communication Foundation。
目标是一个只有五个字段的客户端应用程序;它在其中“发布”到服务器。
- 名字
- 姓氏
- 电子邮件地址
- 电话号码
- 网站地址
这并不太复杂。
这就是我所做的,在我学习 WCF 的过程中,我已经尽可能地接近 OOP 主体,用于基于 SOA 的应用程序。这样,它提供了代码可重用性。
模型/数据合同:
#region Using Reference...
using System.Runtime.Serialization;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Text;
using System.Linq;
using System;
#endregion
namespace _2Do.Model.Customer
{
[DataContract(IsReference = true)]
public class Person
{
#region Declared Variable.
string first;
string last;
string email;
string phone;
string site;
#endregion
#region Constructor:
Person()
{
// Empty Constructor.
}
#endregion
#region Data Member Properties:
[DataMember()]
public string First
{
get { return first; }
set { first = value; }
}
[DataMember()]
public string Last
{
get { return last; }
set { last = value; }
}
[DataMember()]
public string Email
{
get { return email; }
set { email = value; }
}
[DataMember()]
public string Phone
{
get { return phone; }
set { phone = value; }
}
[DataMember()]
public string Site
{
get { return site; }
set { site = value; }
}
#endregion
}
}
这就是应该通过元数据为客户端公开的对象;所以对于服务接口我尝试了这个:
#region Using Reference...
using System.Collections.Generic;
using System.Threading.Tasks;
using System.ServiceModel;
using _2Do.Model.Customer;
using System.Text;
using System.Linq;
using System;
#endregion
namespace _2Do.Contract.Customer
{
[ServiceContract (Namespace = "https://_2Do") ]
public interface IPerson
{
[OperationContract()]
Person SetCustomer(Dictionary<Guid, Person> info);
}
}
所以以上是目标;转移我的 Person 对象;存储到字典中。另一件事要注意;我是否认为通过引用传递值的实现将有助于序列化。我想一旦数据存储在内存中;它将包含一个明确的方法来处理。这是我的错吗?
这就是我的DataContract 和ServiceContract。
此时的实现是这样的:
#region Using Reference...
using System.Collections.Generic;
using System.Threading.Tasks;
using _2Do.Contract.Customer;
using System.ServiceModel;
using _2Do.Model.Customer;
using System.Text;
using System.Linq;
using System;
#endregion
namespace _2Do.Service.Customer
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class PersonService : IPerson
{
#region Constructor:
PersonService()
{
// Empty Constructor.
}
#endregion
#region Implement Interface:
Person SetCustomer(Dictionary<Guid, Person> info)
{
// Receive an error that indicates; best overload method.
// Contains invalid arguments.
}
#endregion
}
}
然后我创建了一个单独的项目来托管应用程序;我创建了一个空文本文件并将其重命名为PersonService.svc。
然后我输入:<%@ ServiceHost Service = "_2Do.Service.Customer.PersonService" %>。
应该指向正确的命名空间;在PersonService 中,我有一个web.config 文件,其中包含要在Internet 信息系统中托管的最低配置。我认为这可以让我绕过定义我的地址、绑定和合同。因为 IIS 现在会为我做这一切。
然后我创建了一个ClientProxy 类;其中包含几乎是DataContract 的镜像。然后我创建了实际的客户端应用程序:
PersonProxy p = new PersonProxy();
p.First = txtFirst.Text;
p.Last = txtLast.Text;
p.Email = txtEmail.Text;
p.Phone = txtPhone.Text;
p.Site = txtSite.Text;
Dictionary<Guid, Person> i = new Dictionary<Guid, Person>();
i.Add(Guid.NewGuid(), p);
我有这些项目:
- 模型 --> DataContract
- 合同 --> 服务合同
- 服务 --> 接口实现
- Host --> Stores Service / Svc
- ClientProxy --> 接口实现
- Client --> 链接到 ClientProxy 要继承的实际值。
这就是我在客户端上使用它的方式。我不确定我在哪里搞砸了。我真的很想了解 WCF,因为我需要为工作项目学习它。但是我很沮丧,觉得自己很愚蠢,因为我似乎无法解决这个问题。
如果我按照教程进行操作,它会起作用。但是一旦我回到原来的实现,它就会失败。不知道我哪里出错了。一些手握将不胜感激;但如果你能一步一步地解释它,那将不胜感激。所以我可以从错误中吸取教训,从而真正改进。
我无法让它将变量存储在服务器上,传输,我现在不知道为什么。
【问题讨论】:
-
我目前的猜测是您没有正确设置 Data Contract 类。我认为您需要另一个派生自
Dictionary并具有CollectionDataContract属性集的类。我正在复制您的代码以进行检查。 -
如果你能让它工作,我将成为有史以来最快乐的人;老实说,我根本无法让这种愚蠢的服务发挥作用。感谢您的回复和帮助。
-
奇怪,我的代码似乎可以传递参数和结果。您使用的是什么版本的框架?
-
另一件事(非 WCF):确保
PersonService中的SetCustomer方法标记为public。 -
Framework 4.5 不知道是不是因为我分离了Assemblies。或者如果我搞砸了主机/客户端代理。
标签: c# wcf web-services generics iis