C # - Совет по проектированию проблемы: не может использовать словарь, то что? - PullRequest
3 голосов
/ 06 апреля 2011

Мне нужно вернуть словарь (или некоторый список, я просто не знаю) через веб-службу, в частности, через службы данных WCF. Похоже, что службы данных WCF не поддерживают типы словарей.

Что-то похожее на веб-сервис:

<?xml version="1.0" encoding="utf-8" standalone="yes" ?> 
- <Employees xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices">
    <element>employee1, True</element> 
    <element>employee2, False</element>
    <element>employee3, True</element>
  </Employees>

Сначала я попробовал 1-мерный массив, и это, кажется, работает, но, конечно, только приносит 1-мерный массив с 3 элементами:

[WebGet]
public string[] Employees()
{
   return new[]
   {
        "employee1",
        "employee2",
        "employee3"
   };
}

По сути, мне нужен список (?) С двумя параметрами в каждом, то есть EmployeeName и логическим значением IsActive.

Любой совет будет с благодарностью.

Обновление: я добавил в свой веб-сервис следующее:

public class Employee
    {
        public string Name{ get; set; }
        public bool IsActive{ get; set; }

        public Employee(string name, bool isActive)
        {
            Name = name;
            IsActive = isActive;
        }
    }

[WebGet]
        public List<Employee> Employees()
        {
            var emp1 = new Employee("Test1", true);
            var emp2 = new Employee("Test2", true);
            var list = new List<Employee> { emp1, emp2 };
            return list;
        }

И когда мне нравится файл .svc через мой веб-браузер, я получаю это при загрузке:

Request Error

The server encountered an error processing the request. The exception message is 'Unable to load metadata for return type 'System.Collections.Generic.List`1[Web.Employee]' of method 'System.Collections.Generic.List`1[.Web.Employee] Employees()'.'. See server logs for more details. The exception stack trace is: 

at System.Data.Services.Providers.BaseServiceProvider.AddServiceOperation(MethodInfo method, String protocolMethod) at System.Data.Services.Providers.BaseServiceProvider.AddOperationsFromType(Type type) at System.Data.Services.DataService`1.CreateProvider() at System.Data.Services.DataService`1.HandleRequest() at System.Data.Services.DataService`1.ProcessRequestForMessage(Stream messageBody) at SyncInvokeProcessRequestForMessage(Object , Object[] , Object[] ) at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs) at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc) at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

Есть идеи?

Обновление 2:

Вот дополнительная информация о моем классе DataService.svc. Я использую V2 служб данных WCF с платформой .NET 4.0:

public class WebDataService : DataService<MyModelEntities>
    {
        public static void InitializeService(DataServiceConfiguration config)
        {
            config.UseVerboseErrors = true;
            config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
            config.SetEntitySetAccessRule("*", EntitySetRights.AllRead | EntitySetRights.AllWrite);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
        }

Ответы [ 5 ]

6 голосов
/ 06 апреля 2011

Почему бы вам просто не создать пользовательский тип данных с двумя атрибутами: строкой и логическим значением?

public class MySillyWCFObject
{ 
 boolean b;
 string name;

 public MySillyWCFObject(boolean b, string s)
  {
   this.b = b;
   this.name = s;
  }
}

Тогда вы можете сказать:

MySillyWCFObject m = new MySillyWCFObject(true, "Hi");
1 голос
/ 06 апреля 2011

Если вам не нужно создавать свой собственный класс только для этого, вы можете использовать Tuple:

var tuple = Tuple.Create(true, "Hi");

Это создаст Tuple<bool, string> путем выводатипы из параметров вызова метода.Затем вы можете получить доступ к true и "Hi" как Tuple.Item1 и Tuple.Item2.

0 голосов
/ 07 апреля 2011

Можете ли вы попробовать вернуть IQueryable вместо List?В этом случае ваш возврат будет изменен на return list.AsQueryable();.Также вам необходимо добавить атрибут [DataServiceKey] в класс Employee (например, [DataServiceKey ("Name")]).

0 голосов
/ 06 апреля 2011

вы можете создать небольшой класс объектов переноса, например:

[DataContract]
public class EmployeeDTO {

public EmployeeDTO(string empName,bool isActive){
   EmployeeName = empName;
   IsActive = isActive;
}
[DataMember]
public string EmployeeName {get;private set;}
[DataMember]
public bool IsActive {get;private set;}

}

Ваш метод обслуживания

[WebGet]
public EmployeeDTO[] Employees(){
 return new []{new EmployeeDTO("employee1",true),
               new EmployeeDTO("employee2",false),
               new EmployeeDTO("employee3",true),};
}
0 голосов
/ 06 апреля 2011

Я использовал это раньше Как вернуть универсальный словарь в веб-сервис .

Это код для предоставления вам сериализуемого словаря. Работает отлично. У нас есть система реального времени, которая обходит их, и она отлично работает.

...