【问题标题】:Implementing IEnumerable in WCF在 WCF 中实现 IEnumerable
【发布时间】:2022-02-11 11:10:39
【问题描述】:

我正在学习 WCF,并在具有自己的 GetEnumerator() 方法的接口中制作了自定义类的 C# 小提琴来自定义类的 foreach 行为。类如图:

ProductClass.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;

namespace ProductInterfaces
{
    public class ProductData : IEnumerable
    {
        public string Name { get; set; }
        public string ProductNumber { get; set; }
        public string Color { get; set; }
        public double ListPrice { get; set; }


        List<string> myData = new List<string>(new string[] { "test1", "test2", "test3", "test4" });
        
        public IEnumerator<string> GetEnumerator()
        {
            foreach(string val in myData)
            {
                yield return val;
            }
        }
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
}

而合约如图(IWCFProductService.cs):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace ProductInterfaces
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IWCFProductService" in both code and config file together.
    [ServiceContract]
    public interface IWCFProductService
    {
        [OperationContract]
        ProductData GetProduct(string productNumber);
    }
}

GetProduct()方法的实现如图:

using ProductInterfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace ProductService

{
    public class WCFProductService : IWCFProductService
    {
        public ProductData GetProduct(string productNumber)
        {
            using (adventureworksEntities database = new adventureworksEntities())
            {
                var table_of_products = database.products;
                ProductData desired_product = new ProductData();
                foreach (var p in table_of_products)
                {
                    if (p.ProductNumber == productNumber)
                    {
                        Console.WriteLine("Test using a custom foreach of ProductData class");
                        foreach (string i in desired_product)
                        {
                            Console.WriteLine(i);
                        }
                        desired_product.Name = p.Name;
                        desired_product.ProductNumber = p.ProductNumber;
                        desired_product.Color = p.Color;
                        desired_product.ListPrice = p.ListPrice;
                        return desired_product;
                    }
                }
                throw new Exception();
            }
        }
    }
}

当被客户端调用时:

using ProductInterfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;

namespace ProductClient
{
    class Program
    {
        static void Main(string[] args)
        {
            // Client creates channel factory by passing in the name of the endpoint (i.e. ProductServiceEndpoint)
            ChannelFactory<IWCFProductService> channelFactory = new ChannelFactory<IWCFProductService>("ProductServiceEndpoint");

            // Create a proxy i.e. create a channel
            IWCFProductService proxy = channelFactory.CreateChannel();

            Console.WriteLine("Input product name to be searched:");
            string input = Console.ReadLine();
            var searchResult = proxy.GetProduct(input);

            Console.WriteLine(searchResult.Name);
            Console.ReadLine();
        }
    }
}

它在var searchResult = proxy.GetProduct(input); 失败,除了说

System.ServiceModel.CommunicationException: 'An error occurred while receiving the HTTP response to http://localhost:9999/ProductService. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details.'

我做了一些试验和错误,如果我删除 IEnumerable 和 foreach 循环,没有问题,searchResult 是一个有效的对象。为什么会这样?我是不是理解错了?

【问题讨论】:

  • 其他功能好用吗??
  • 打开跟踪和消息记录以获取有关失败原因的更多详细信息

标签: c# .net wcf


【解决方案1】:

我觉得应该是序列化问题,WCF需要有具体的类来传递数据。
它无法返回 IEnumerable - 尝试使用 List(或 T[] 数组)或具体类型。

您也可以使用Service Trace Viewer 查找具体问题。

有类似问题的帖子
WCF Web Service error: "Service endpoint binding not using HTTP protocol"?
This could be due to the service endpoint binding not using the HTTP protocol

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-04
    • 1970-01-01
    • 2011-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多