Произошла ошибка при попытке сериализации параметра http://tempuri.org/:callback - PullRequest
2 голосов
/ 14 мая 2011

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

Однако, когда этот метод вызывается:

public IAsyncResult Beginxxx(string path, AsyncCallback callback, object state)  
{
    return Channel.Beginxxx(path, callback, state); 
}

Я получаю это исключение:

{"Произошла ошибка при попытке сериализации параметра http://tempuri.org/:callback. Сообщение InnerException было 'Type' System.DelegateSerializationHolder + DelegateEntry 'с именем контракта данных'DelegateSerializationHolder.DelegateEntry: http://schemas.datacontract.org/2004/07/System' не ожидается. Добавьте любые типы, которые не известны статически, в список известных типов - например, с помощью атрибута KnownTypeAttribute или добавив их в список известных типов, передаваемых в DataContractSerializer. 'InnerException для получения более подробной информации. "}

Если бы у меня был свой собственный класс со своими собственными свойствами, это исключение имело бы смысл, но это стандартный тип .NET (AsyncCallback, на который, я полагаю, относится и к исключению),Пример кода того, что я пытаюсь сделать, не имеет этой проблемы (и я изменил ее на тот же тип привязки, который я использую - именованные каналы).

Что не так?

1 Ответ

6 голосов
/ 14 мая 2011

Возможно, вы забыли добавить свойство (AsyncPattern = true) в атрибуте [OperationContract].В приведенном ниже примере показаны два клиента: один (неправильный) с точной ошибкой, которую вы видите, другой (правильный), которая работает.Единственное отличие - AsyncPattern = true в операционном контракте.

    public class StackOverflow_5999249_751090
{
    [ServiceContract(Name = "ITest", Namespace = "")]
    public interface ITest
    {
        [OperationContract]
        string Echo(string path);
    }

    public class Service : ITest
    {
        public string Echo(string path) { return path; }
    }

    [ServiceContract(Name = "ITest", Namespace = "")]
    public interface ITestClient_Wrong
    {
        [OperationContract]
        IAsyncResult BeginEcho(string path, AsyncCallback callback, object state);
        string EndEcho(IAsyncResult asyncResult);
    }

    [ServiceContract(Name = "ITest", Namespace = "")]
    public interface ITestClient_Correct
    {
        [OperationContract(AsyncPattern = true)]
        IAsyncResult BeginEcho(string path, AsyncCallback callback, object state);
        string EndEcho(IAsyncResult asyncResult);
    }

    static void PrintException(Exception e)
    {
        int indent = 2;
        while (e != null)
        {
            for (int i = 0; i < indent; i++)
            {
                Console.Write(' ');
            }

            Console.WriteLine("{0}: {1}", e.GetType().FullName, e.Message);
            indent += 2;
            e = e.InnerException;
        }
    }

    public static void Test()
    {
        string baseAddress = "net.pipe://localhost/Service";
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        host.AddServiceEndpoint(typeof(ITest), new NetNamedPipeBinding(), "");
        host.Open();
        Console.WriteLine("Host opened");

        AutoResetEvent evt = new AutoResetEvent(false);

        Console.WriteLine("Correct");
        ChannelFactory<ITestClient_Correct> factory1 = new ChannelFactory<ITestClient_Correct>(new NetNamedPipeBinding(), new EndpointAddress(baseAddress));
        ITestClient_Correct proxy1 = factory1.CreateChannel();
        proxy1.BeginEcho("Hello", delegate(IAsyncResult ar)
        {
            Console.WriteLine("Result from correct: {0}", proxy1.EndEcho(ar));
            evt.Set();
        }, null);
        evt.WaitOne();

        Console.WriteLine("Wrong");
        ChannelFactory<ITestClient_Wrong> factory2 = new ChannelFactory<ITestClient_Wrong>(new NetNamedPipeBinding(), new EndpointAddress(baseAddress));
        ITestClient_Wrong proxy2 = factory2.CreateChannel();
        try
        {
            proxy2.BeginEcho("Hello", delegate(IAsyncResult ar)
            {
                try
                {
                    Console.WriteLine("Result from wrong: {0}", proxy2.EndEcho(ar));
                }
                catch (Exception e)
                {
                    PrintException(e);
                }
                evt.Set();
            }, null);
            evt.WaitOne();
        }
        catch (Exception e2)
        {
            PrintException(e2);
        }

        Console.WriteLine("Press ENTER to close");
        Console.ReadLine();
        host.Close();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...