почему мой клиент WCF получает пустой результат? - PullRequest
0 голосов
/ 16 июля 2009

Я использую VSTS 2008 + .Net + C # 3.5 для разработки службы WCF (самостоятельно размещенной в качестве службы Windows). Со стороны клиента я использую ChannelFactory для подключения к службе WCF. Моя путаница заключается в том, что когда я изменяю код на стороне клиента с «ответа на открытую строку» на «ответ на открытую строку», значение responseAliasName равно нулю. Но при переходе обратно к ответу с именем переменной значение ответа будет правильным (значение «привет WCF»).

Моя путаница в том, что я думаю, что имя переменной не должно иметь значения, если расположение одинаково как на стороне клиента, так и на стороне сервера. Есть идеи, что не так?

Код серверной стороны:

namespace Foo
{
    // NOTE: If you change the interface name "IService1" here, you must also update the reference to "IService1" in Web.config.
    [ServiceContract]
    public interface IFoo
    {
        [OperationContract]
        FooResponse Submit(string request);
    }

    [DataContract]
    public class FooResponse
    {
        [DataMember]
        public string response;
    }
}

namespace Foo
{
    // NOTE: If you change the class name "Service1" here, you must also update the reference to "Service1" in Web.config and in the associated .svc file.
    public class FooImpl : IFoo
    {
        public FooResponse Submit(string request)
        {
            FooResponse foo = new FooResponse();
            foo.response = "hi WCF";
            return foo;
        }
    }
}

Код на стороне клиента:

namespace Foo
{
    // NOTE: If you change the interface name "IService1" here, you must also update the reference to "IService1" in Web.config.
    [ServiceContract]
    public interface IFoo
    {
        [OperationContract]
        FooResponse Submit(string request);
    }

    [DataContract]
    public class FooResponse
    {
        [DataMember]
        // public string responseAliasName;
        public string response;
    }
}


namespace FooTestClient1
{
    class Program
    {
        static void Main(string[] args)
        {
            ChannelFactory<IFoo> factory = new ChannelFactory<IFoo>(
               "IFoo");
            IFoo f = factory.CreateChannel();
            FooResponse response = f.Submit("Hi!");

            return;
        }
    }
}

Ответы [ 4 ]

2 голосов
/ 16 июля 2009

вы можете использовать

[DataContract(Name="ResponseAliasName")]
public string response;

на стороне сервера, и он будет работать так, как вы ожидаете, DataContract по умолчанию использует имя поля или свойства для сериализации данных, и сервер не может найти правильные данные

1 голос
/ 16 июля 2009

Мое замешательство, когда Я изменяю код на стороне клиента от "public строковый ответ "to" публичная строка responseAliasName ", значение responseAliasName равно нулю. Но когда вернуться к ответу с именем переменной, значение ответа является правильным (значение это "привет WCF"). Мое замешательство, я думаю, имя переменной не должно иметь значения до тех пор, пока макет такой же от клиента и серверная сторона. Есть идеи, что не так?

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

ChannelFactory<IFoo> factory = new ChannelFactory<IFoo>("IFoo");
IFoo f = factory.CreateChannel();
FooResponse response = f.Submit("Hi!");

Это будет работать - без проблем:

FooResponse myResponseVar1 = f.Submit("Hi!");

и так будет:

FooResponse someReallyCleverVariableNameWhateverItMightBe = f.Submit("Hi!");

Но DataContract , конечно, является общим элементом , о котором сервис и клиент должны договориться! Вы не можете локально изменить имена элементов в контракте данных - в конце концов, это то, что действительно описывает, как ваши вызовы будут превращены в сообщение XML, и эти фрагменты должны оставаться синхронизированными между сервером и клиентом чтобы клиент мог превратить полученное от сервера сообщение обратно в объект для использования.

ServiceContract и DataContract должны быть одинаковыми на обоих концах - это основное требование, в противном случае, почти ничего не происходит вообще.

Марк

1 голос
/ 16 июля 2009

Джордж, почему бы просто не использовать «Add Service Reference» для создания своего клиента? Как видите, создавать контракты на обслуживание на стороне клиента опасно.

1 голос
/ 16 июля 2009

Нет, имя участника включено в сериализацию. Если вы измените его на стороне клиента, он не сможет десериализоваться обратно в этот член.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...