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.csnamespace 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?
- 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.
- 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
orpublic 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 writepublic User Content
. It will work and the client will know what to expect in service response.
精彩评论