好的,我在解决特定问题时遇到了很多困难。通过服务传输对象。从概念上讲,这是有道理的……我认为?据我所知,除非已明确定义,否则无法序列化泛型。
所以我想举个例子;我根本无法工作。意思是;我敢肯定还有其他人也遇到了一些困难。当您协助时,如果您可以提供代码;那会起作用并解释它。这样我就可以完全理解这个问题。这将帮助我更好地理解 Windows Communication Foundation。
目标是一个只有五个字段的客户端应用程序;它在其中“发布”到服务器。
- 名字
- 姓氏
- 电子邮件地址
- 电话号码
- 网站地址
这并不太复杂。
以下是我所做的,在我学习 WCF 的过程中,我已经尽可能接近 OOP Principals,以用于基于 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
}
}
这就是应该通过元数据为客户端公开的对象;所以对于服务接口(interface),我尝试这样做:
#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);
}
}
所以以上就是目标;转移我的个人对象;存入字典。另一件事要注意;我认为通过引用传递值的实现将有助于序列化。我想一旦数据存储在内存中;它将包含一个明确的处理方法。这是我的错吗?
那是我的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 信息系统中的最低限度配置的文件。我认为这可以让我绕过定义我的地址、绑定(bind)和契约(Contract)。因为 IIS 现在会为我做这一切。
然后我创建了一个 ClientProxy
类(class);其中包含几乎 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);
我有这些项目:
- 模型 --> 数据合约
- 契约(Contract) --> 服务契约(Contract)
- 服务 --> 接口(interface)实现
- Host --> Stores Service/Svc
- ClientProxy --> 接口(interface)实现
- Client --> 链接到 ClientProxy 继承的实际值。
这就是我在客户端上使用它的方式。我不确定我在哪里搞砸了。我真的很想了解 WCF,因为我需要为工作项目学习它。但我很沮丧,觉得自己很愚蠢,因为我似乎无法解决这个问题。
如果我按照教程进行操作,它就会起作用。但是一旦我回到原来的实现,它就会失败。不确定我哪里出错了。一些牵手将不胜感激;但如果你能一步一步地解释它,我们将不胜感激。这样我就可以从错误中吸取教训以实际改进。
我无法让它在服务器上存储变量,传输,此时我不知道为什么。
最佳答案
我仍然不确定为什么您的代码无法正常工作。也许我不了解 IIS 中的托管以及我应该了解的内容。但是,下面是我能想到的最简单的 Web 服务 + 客户端的完整工作示例。希望它能帮助您找到并解决问题。
首先,project structure : 一个类库项目中的契约(Contract),控制台应用程序中的服务和主机,不同控制台应用程序中的客户端。
数据契约:
[DataContract]
public class Person
{
[DataMember]
public string Name { get; set; }
[DataMember]
public string Email { get; set; }
}
服务契约(Contract):
[ServiceContract]
public interface IPerson
{
[OperationContract]
Person SetCustomer(Dictionary<Guid, Person> info);
}
服务:
public class PersonService : IPerson
{
public Person SetCustomer(Dictionary<Guid, Person> info)
{
foreach (var person in info.Values)
{
Console.WriteLine("Name: {0} | Email: {1}", person.Name, person.Email);
}
var p = new Person { Name = "John Doe", Email = "John@Doe.com" };
return p;
}
}
服务宿主(在宿主项目的 Program.cs 中):
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(PersonService), new Uri("http://localhost:8080")))
{
host.Open();
Console.WriteLine("Ready!");
Console.ReadKey(true);
host.Close();
}
}
最后,客户端(在其自己项目的 Program.cs 中):
static void Main(string[] args)
{
var binding = new BasicHttpBinding();
var endpoint = new EndpointAddress("http://localhost:8080/");
using (var factory = new ChannelFactory<IPerson>(binding, endpoint))
{
var request = new Dictionary<Guid, Person>();
request[Guid.NewGuid()] = new Person { Name = "Bob", Email = "Bob@abc.com" };
var client = factory.CreateChannel();
var result = client.SetCustomer(request);
Console.WriteLine("Name: {0} | Email: {1}", result.Name, result.Email);
factory.Close();
}
Console.ReadKey(true);
}
希望这对您有所帮助!
关于c# - WCF 通用字典和理解 WCF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14062486/