【问题标题】:Wcf ChannelFactoryWcf 通道工厂
【发布时间】:2019-02-11 18:42:19
【问题描述】:

我有一个关于 WCF 和 Channel Factory 使用的问题。

在主机上:

[ServiceContract]
public interface IGetMessage 
{
    [OperationContract]
    string ShowMessage(Sample p, string Username, string Password);
}

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

public string ShowMessage(Sample p, string Username, string Password)
{
    return p.Name.ToString() + " - " + "Correct"; //Error line
}

在客户端:

[ServiceContract()]
public interface IGetMessage
{
    [OperationContract()]
    string ShowMessage(Sample p, string Username, string Password);
}

[DataContract()]
public class Sample
{
    [DataMember]
    public string Name { get; set; }

}

private void button1_Click(object sender, EventArgs e)
{
    Sample p1 = new Sample();
    p1.Name = "ALEX";

    BasicHttpBinding myBinding = new BasicHttpBinding();

    EndpointAddress myEndpoint = new EndpointAddress("http://MYURL/GetMessage.svc");

    using (var myChannelFactory = new ChannelFactory<IGetMessage>(myBinding, myEndpoint))
    {
        IGetMessage client = null;

        try
        {
            client = myChannelFactory.CreateChannel();

            MessageBox.Show(client.ShowMessage(p1, "abc","123"));

            ((ICommunicationObject)client).Close();
            myChannelFactory.Close();
        }
        catch
        {
            (client as ICommunicationObject)?.Abort();
        }
    }

}

如果我将客户端添加为服务参考,它会完美运行。我可以收到“ALEX - 正确”消息。

当我在 WcfTestClient.exe 上进行测试时,它运行良好。

但是,我在 Winform 上使用上述代码时遇到了问题。 当我检查 WcfServer 跟踪日志和消息日志时;

System.NullReferenceException - 对象引用未设置为对象的实例。行号:22

第 22 行: p.Name.ToString() 在 Host 的 GetMessage.cvs.cs 文件中。

我认为,主机上没有问题。问题出在客户端。

我想问你我是怎么在客户端出错的?

问候。

【问题讨论】:

  • 一切看起来都很完美。我在合同中看不到任何差异...除了您在客户端属性上使用 ()
  • 我找不到问题。根据 Wcf Trace Log 和 Message Log;问题是样本类(传递对象)。我确信问题出在客户端。因为我在 wcftestclient.exe 或添加服务引用上没有任何问题。
  • 另外,最后,我添加了 svc url 作为服务参考,并在 Button_Click 上动态更改了端点地址。它运行良好。如果我找不到解决方案,我会按照这种方式进行。
  • 是的,这可能已经足够好了...但是如果您仍然想尝试一些东西...wcf 合同具有命名空间,您可以使用 [ContractNamespace] 属性控制该命名空间。我将我的放在 AssembyInfo.cs 中,并将其作为全局范围的前缀:[assembly:ContractNamespace...] 只是为了恶心,尝试以相同的方式在客户端和服务器中声明它...它们可能会有所不同,以防止反序列化服务器。
  • 您可以查看服务参考(它实际上只是一个包含一些 gen'd 代码的文件夹)并看到它在很大程度上与您的 winforms 客户端做同样的事情......也许在那里寻找一些差异.

标签: c# wcf channelfactory


【解决方案1】:

如 cmets 中所述,要解决此问题,您只需将命名空间属性添加到 ServiceContract 和 DataContract。确保客户端和服务器之间的命名空间相同。我们之所以应该这样做是因为在序列化和反序列化过程中发生了错误,我们必须确保服务合约和数据合约在服务器和客户端之间具有一致的命名空间。
这是我的示例(在服务器和客户端上都添加此功能。)

    [ServiceContract(Namespace ="http://mydomain")]
    public interface IGetMessage
    {
        [OperationContract]
        string ShowMessage(Sample p, string Username, string Password);
    }

    [DataContract(Namespace = "http://mydomain")]
    public class Sample
    {
        [DataMember]
        public string Name { get; set; }
}

结果。

如果有什么可以帮助的,请随时告诉我。

【讨论】:

  • 非常感谢@Abraham Qian。感谢您的正确解决方案。问题是命名空间。问候。
  • 非常感谢@Clay。您的解决方案也在检查名称空间。问题已解决。再次感谢
猜你喜欢
  • 1970-01-01
  • 2011-01-12
  • 2011-12-08
  • 1970-01-01
  • 1970-01-01
  • 2014-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多