Сообщение или тип, который имеет MessageContractAttribute и другие параметры разных типов

Я разрабатываю службы WCF, где некоторые классы имеют атрибут [MessageContract], а некоторые нет.

Когда я пытаюсь запустить службы, я получаю следующее сообщение об ошибке:

Операция "ProcessOperation" не может быть загружена, поскольку она имеет параметр или тип возвращаемого типа типа System.ServiceModel.Channels.Message или тип, который имеет MessageContractAttribute и другие параметры разных типов. При использовании System.ServiceModel.Channels.Message или типов с MessageContractAttribute метод не должен использовать другие типы параметров.

Означает ли это, что все службы должны иметь [MessageContract], хотя они не связаны?

Ответ 1

Нет, это означает, что у вас есть несколько параметров для метода, а некоторые из них не являются сообщениями. Попробуйте отправить интерфейс к вашему сервису.

Это сообщение в блоге объясняет:

... проблема заключается в том, что контракты с сообщениями не могут использоваться одновременно с другими типами параметров. В этом случае возвращаемое значение операции представляет собой строку. Возвращаемые значения - это еще один выходной параметр, поэтому эта операция смешивает сообщение с сообщением о сообщении с примитивным типом параметра. Это выходит из строя, потому что контракты с сообщениями дают вам контроль над компоновкой сообщения SOAP, что препятствует объединению системы в этих дополнительных параметрах.

Важное примечание:

Кстати, сообщение об ошибке, которое вы получаете, когда вы пытаетесь смикшировать контракты с сообщениями, выглядит следующим образом.

Ответ 2

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

MixType1: Contract type and primitive types as operation parameters
MixType2: Contract type as a parameter and primitive type as return type
MixType3: Primitive type as a parameter and Contract type as return type

Любой из перечисленных выше сценариев создаст ошибку.

Ответ 3

Решено!

Я не могу вернуть String, я возвращаю объект приветствия клиенту.

using System;
using System.ServiceModel;
using System.Net.Security;

namespace com.blogspot.jeanjmichel.model
{
    [MessageContract]
    public class Greeting
    {
        private String userGreeting;

        private void SetGreeting()
        {
            DateTime now = DateTime.Now;

            if (now.Hour >= 7 && now.Hour <= 11)
            {
                this.userGreeting = "Good morning";
            }
            else if (now.Hour >= 12 && now.Hour <= 17)
            {
                if (now.Hour == 12 || now.Hour == 13)
                {
                    this.userGreeting = "Good afternoon, it lunch time!";
                }
                else
                {
                    this.userGreeting = "Good afternoon";
                }
            }
            else if (now.Hour >= 18 && now.Hour <= 20)
            {
                this.userGreeting = "Good evening";
            }
            else
            {
                this.userGreeting = "Good night";
            }
        }

        [MessageBodyMember(Order = 1, ProtectionLevel = ProtectionLevel.EncryptAndSign)]
        public String UserGreeting
        {
            get { return this.userGreeting; }
        }

        public Greeting()
        {
            this.SetGreeting();
        }
    }
}

using System;
using System.ServiceModel;
using com.blogspot.jeanjmichel.model;

namespace com.blogspot.jeanjmichel.services.contract
{
    [ServiceContract(Namespace = "http://jeanjmichel.blogspot.com/services/v0.0.1")]
    public interface IGetGreeting
    {
        [OperationContract]
        Greeting GetGreeting(Credential credential);
    }
}

using System;
using System.ServiceModel;
using com.blogspot.jeanjmichel.services.contract;
using com.blogspot.jeanjmichel.model;

namespace com.blogspot.jeanjmichel.services
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall,
                     Namespace = "http://jeanjmichel.blogspot.com/services/v0.0.1")]
    public class GetGreetingService: IGetGreeting
    {
        public Greeting GetGreeting(Credential credential)
        {
            if (String.IsNullOrEmpty(credential.Token))
            {
                throw new FaultException("Inform the security phrase, and try again.");
            }
            else
            {
                if (credential.Token.Equals("[email protected]"))
                {
                    Greeting g = new Greeting();
                    return g;
                }
                else
                {
                    throw new FaultException("Wrong password.");
                }
            }
        }
    }
}

Ответ 4

Если у вас есть проблема со смешанными типами примитива (например, строка) и MessageContract в качестве другого типа, то есть один класс как возвращаемый и строковый параметр, один из способов, которым я решил это, заключался в переключении с MessageContract на DataContract.

Другим способом решения этого вопроса будет создание класса для хранения вашего примитивного типа в качестве свойства, так что и ваш возврат, и параметр могут реализовать MessageContract.

Ответ 5

Когда вы используете объект Message в качестве параметра, метод должен возвращать void