Не могу отправить что-либо, что не является универсальным типом - PullRequest
5 голосов
/ 01 июня 2011

У меня есть приложение на основе этого урока

Метод, который я использую для получения списка пользователей из сервиса:

public class PBMBService : IService
{
    public ServiceResponse UserList()
    {
        try
        {
            sql.Open();
            List<User> result = new List<User>();

            //filling list from database

            return new ServiceResponse(SRFlag.OK, result);
        }
        catch (Exception ex)
        {
            return new ServiceResponse(SRFlag.EXCEPTION, ex);
        }


    }

//other methods
}

Сервисная основная функция:

class Program
{
    static void Main(string[] args)
    {
        Uri baseAddress = new Uri("http://localhost:8000/PBMB");

        ServiceHost selfHost = new ServiceHost(typeof(PBMBService), baseAddress);

        try
        {
            selfHost.AddServiceEndpoint(
                typeof(IService),
                new WSHttpBinding(),
                "PBMBService");

            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            smb.HttpGetEnabled = true;
            selfHost.Description.Behaviors.Add(smb);

            selfHost.Open();
            Console.WriteLine("Serwis gotowy.");
            Console.WriteLine("Naciśnij <ENTER> aby zamknąć serwis.");
            Console.WriteLine();
            Console.ReadLine();


            selfHost.Close();
        }
        catch (CommunicationException ce)
        {
            Console.WriteLine("Nastąpił wyjątek: {0}", ce.Message);
            selfHost.Abort();
        }
    }
}

Другие классы в
Classes.cs

namespace PBMB
{
public enum SRFlag { OK, EXCEPTION };

[DataContract]
public class ServiceResponse
{
    private SRFlag _flag;
    private Object _content;

    public ServiceResponse(SRFlag srf, Object c)
    {
        _flag = srf;
        _content = c;
    }

    [DataMember]
    public SRFlag Flag
    {
        set { _flag = value; }
        get { return _flag; }
    }

    [DataMember]
    public Object Content
    {
        set { _content = value; }
        get { return _content; }
    }
}

[DataContract]
public class User
{
    [DataMember]
    public string Login { get; set; }
    [DataMember]
    public string FirstName { get; set; }
    [DataMember]
    public string MiddleName { get; set; }
    [DataMember]
    public string LastName { get; set; }
    [DataMember]
    public string Email { get; set; }
}
}

Мой вопрос: почему я не могу отправить что-либо, не являющееся универсальным типом? Мне нужно отправить List<User> или User[], но я даже не могу отправить int[2] (возможна отправка int или string).

Когда я пытаюсь отправить Список от службы к клиенту, служба работает, но в клиенте появляется исключение:

An error occurred while receiving the HTTP response to http://localhost:8000/PBMB/PBMBService.  
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.  

1 Ответ

3 голосов
/ 01 июня 2011

Полагаю, это происходит потому, что класс User объявлен как DataContract, а сериализатор данных может его сериализовать и десериализовать.

Однако объявлять объект как часть возвращаемого ответа - очень плохая идея.,Вы должны всегда указывать тип, который возвращается.Возвращаемый объект противоречит принципам передачи сообщений.Сервисный клиент должен иметь возможность получать всю информацию, необходимую от wsdl, и это в принципе невозможно, если вы определите часть ответа как объект (какой объект? Конкретный объект .net? И т. Д.). Принципы передачи сообщений просто отличаются от объектно-ориентированных.принципы.

Также, если вы хотите вернуть исключения клиентам, отметьте FaultException .

ОБНОВЛЕНИЕ:

Как это решить?

  1. Измените свой дизайн - не ожидайте, что вы можете просто отправить любой объект.Это неверное предположение, когда речь идет о SOA и передаче сообщений.
  2. Если вы хотите отправлять объекты базовых типов, таких как int, просто укажите в своем ответе string, что вы вернете public string Content или public int Number- так же, как вы это сделали, но указывайте тип явно (не используйте объект).Если вы хотите вернуть пользовательский класс, то есть User, объявите его так же, как вы (DataContract, DataMember и т. Д. - но это не обязательно), и просто напишите public User Content.Это сработает, и клиент будет знать, чего ожидать в ответе службы.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...