开发者

Can't send anything that is not generic type

开发者 https://www.devze.com 2023-03-10 00:33 出处:网络
I have application based on this tutorial Method I use to get user list from service: public class PBMBService : IService

I have application based on this tutorial

Method I use to get user list from service:

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
}

Service main function:

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();
        }
    }
}

Other classes are in

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; }
}
}

My question is: why I can't send anything that is not generic type? I need to send List<User> or User[] but I can't even send int[2] (sending int or string is possible).

When I try to send List from service to client, service works but I get exception in client:

An error occurred while receiving the HTTP response to http://localhost:8000/PBMB/PBMBService.  
This could be due 开发者_如何学Pythonto 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.  


I guess this happens because User class is declared as DataContract and data serializer is able to serialize and deserialize it.

However, it is a very bad idea to declare object as a part of response that is returned. You should always specify the type that is returned. Returning object is against message passing principles. Service client should be able to obtain all the information needed from wsdl and it is basically impossible if you define part of the response as object (what kind of object? .net specific object? etc.) Message passing principles are simply different than object oriented principles.

Also if you want to return exceptions to clients check FaultException.

UPDATE:

How to solve it?

  1. Change your design - don't expect you can just send any object. This is a wrong assumption when it comes to SOA and message passing.
  2. If you want to send objects of basic types such as int, string just declare in your response that you will return public string Content or public int Number - just like you did but state the type explicitly (don't use object). If you want to return custom class i.e. User, declare it just like you did (DataContract, DataMember, etc - however it is not necessary) and just write public User Content. It will work and the client will know what to expect in service response.
0

精彩评论

暂无评论...
验证码 换一张
取 消