Wcf возвращает данные внутри свойства DataSet и возвращает другие свойства как нулевые - PullRequest
0 голосов
/ 09 января 2019

У меня служба WCF возвращает следующий DataContract:

[DataContract]
public class Employee
{
    [DataMember]
    public DataSet DS { get; set; }

    [DataMember]
    public string ID { get; set; }

    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public string Email { get; set; }

}

А внутри службы GetEmployee я возвращаю объект Employee, но значение всех столбцов возвращается как нулевое, кроме свойства DS, которое содержит значения свойств Employee в списке узлов.

public Employee GetEmployee()
    {
            return new Employee
            {
                ID = "76072",
                Name = "name",
                Email = "emp@test.com",
                DS = null
            };
    }

Но если я удалю свойство DS из Employee DataContract, он вернет данные в свойствах правильно.

У меня вопрос, почему WCF неявно возвращает данные внутри свойства DataSet?

Ответы [ 3 ]

0 голосов
/ 10 января 2019

Я решил это, назначив новый объект Dataset () вместо null, как показано ниже:

public Employee GetEmployee()
{
        return new Employee
        {
            ID = "76072",
            Name = "name",
            Email = "emp@test.com",
            DS = new DataSet()
        };
}

Теперь в клиенте службы WCF свойства сотрудника отображаются правильно, а не возвращаются в свойство DS.

0 голосов
/ 11 января 2019

Я неправильно понял ваш вопрос или где я потерял конфигурацию? Я не мог воспроизвести вашу проблему, ссылаясь на ваши шаги. На моей стороне. клиент мог нормально получать правильные значения. Я предлагаю вам добавить пространство имен в контракт данных.
Вот мое демо, желаю, чтобы оно вам пригодилось.
Сервер (IP: 10.157.13.69)

    class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost sh = new ServiceHost(typeof(MyService)))
            {
                sh.Opened += delegate
                {
                    Console.WriteLine("service is ready...");
                };
                sh.Closed += delegate
                {
                    Console.WriteLine("Service is closed");
                };
                sh.Open();
                Console.ReadLine();
                sh.Close();
            }
        }
    }
    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        Product SayHello();
    } 
    public class MyService : IService
    {
        public Product SayHello()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add(new DataColumn("ID", typeof(int)));
            dt.Columns.Add(new DataColumn("Name", typeof(string)));
            dt.Rows.Add(10, "Lemon");
            dt.Rows.Add(11, "Peach");
            DataSet ds = new DataSet();
            ds.Tables.Add(dt);
            return new Product()
            {
                Id = 1,
                Name = "Apple",
                DS = ds
            };
        }
    }

    [DataContract(Namespace ="MyCorporation")]
     public class Product
    {
        [DataMember]
        public DataSet DS { get; set; }
        [DataMember]
        public int Id { get; set; }
        [DataMember]
        public string Name { get; set; }
}

App.config (сервер)

<system.serviceModel>
    <services>
      <service name="Server6.MyService" behaviorConfiguration="mybeh">
        <endpoint address="" binding="basicHttpBinding" contract="Server6.IService" >
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:13060"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="mybeh">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"></serviceMetadata>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

Клиент.

class Program
    {
        static void Main(string[] args)
        {
            ServiceReference1.ServiceClient client = new ServiceReference1.ServiceClient();
            try
            {
                var result = client.SayHello();
                var r2 = result.DS.Tables[0];
                Console.WriteLine($"{result.Id},{result.Name}");
                Console.WriteLine($"{r2.Rows[0][0]},{r2.Rows[0][1]}\n{r2.Rows[1][0]},{r2.Rows[1][1]}");
            }
            catch (Exception)
            {
                throw;
            }

        }
}

App.config (клиент).

    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IService" />
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://10.157.13.69:13060/" binding="basicHttpBinding"
                bindingConfiguration="BasicHttpBinding_IService" contract="ServiceReference1.IService"
                name="BasicHttpBinding_IService" />
        </client>
</system.serviceModel>

Result.
enter image description here
Не стесняйтесь, дайте мне знать, если есть что-то, с чем я могу помочь.

0 голосов
/ 09 января 2019

Я бы не рекомендовал использовать объект набора данных в качестве свойства для передачи в WCF. Это огромная нагрузка на WCF. Хотя это может не совсем ответить на ваш вопрос, Скотт Хансельман поддерживает меня в этом: Возвращение наборов данных в веб-сервисах - это порождение сатаны

...