好吧,我在解决特定问题时遇到很多困难。通过服务传输对象。从概念上讲,这很有意义...我认为吗?根据我的阅读,除非已明确定义泛型,否则无法对其进行序列化。

因此,我想提供我的例子;我根本无法上班。意思是;我相信还有其他人也会遇到一些困难。如果可以的话,您可以提供代码;会起作用并解释它。这样我就可以完全理解这个问题。这将对我有所帮助,有助于理解Windows Communication Foundation。

目标是仅包含五个字段的客户端应用程序。在其中“发布”到服务器。


名字

电子邮件地址
电话号码
网站地址


不太复杂。

这就是我所做的,在学习WCF的过程中,我已尽可能地将其包含在基于SOA的应用程序中的OOP主体中。这样,它提供了代码可重用性。

型号/数据合同:

#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对象;存储到字典中。另一件事要注意;我认为通过引用传递值的实现将有助于序列化。我发现数据一旦存储在内存中就可以了。它包含一个明确的方法来处理。我这是错的吗?

这就是我的DataContractServiceContract

此时的实现是这样的:

#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 Information System中托管的最起码的最低配置。我认为可以绕开定义我的地址,绑定和合同。 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
合同-> ServiceContract
服务->接口的实现
主机->商店服务/服务
ClientProxy->接口的实现
客户端->链接到ClientProxy继承的实际值。


这就是我在客户端上使用它的方式。我不确定我在哪里搞砸了。我真的很想了解WCF,因为我需要在工作项目中学习它。但是我感到沮丧和愚蠢,因为我似乎无法解决这个问题。

如果我按照教程进行操作,它将起作用。但是一旦我回到最初的实现,它就会失败。不知道是什么地方或哪里出了问题。一些手将不胜感激;但如果您可以逐步解释它,将不胜感激。因此,我可以从自己的错误中吸取教训,以进行实际的改进。

我无法获取将变量存储在服务器上并进行传输的信息,现在我也不知道为什么。

最佳答案

我仍然不确定为什么您的代码无法正常工作。也许我不太了解IIS中的托管。但是,下面是我可以想到的最简单的Web服务+客户端的完整示例。希望它将帮助您找到并解决该问题。

首先,project structure:在一个类库项目中签订合同,在控制台应用程序中提供服务和主机,在另一个控制台应用程序中提供客户端。

数据合约:

[DataContract]
public class Person
{
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public string Email { get; set; }
}


服务合约:

[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);
}


希望这可以帮助!

08-03 23:22