Pergunta

A fim de obter um serviço WCF trabalhando com JQuery eu adicionei um atributo WebInvoke no contrato de operação para controlar a serialização JSON da seguinte forma:

[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]

Existe uma maneira de controlar este serialização através das ligações de serviço na configuração ao invés, uma vez que limita este serviço de fornecer diferentes serializações a diferentes pontos finais.

Foi útil?

Solução

Eu tenho uma solução diferente, que funciona na extremidade oposta de @ Marc Gravell de: em vez de duplicar o contrato, derivam 2 classes diferentes do serviço aplicação . Estes são aliases Basta digitar; eles são necessários porque o sistema de ativação WCF (como menos no IIS) não permitirá que você para ativar o mesmo tipo de serviço em diferentes URLs (não tenho certeza por isso que a solução da Gravell não executar para esse problema - o erro que eu sou recebendo é "Um registro já existe para URI ..." quando tento ativar a mesma classe de serviço em diferentes URLs no mesmo local). Note-se que este é apenas um problema se você deseja executar o mesmo serviço com varíola e JSON simultaneamente . Se tudo que você quer é controlar o formato de resposta, você não precisa esta solução alternativa.

O conceito chave por trás da minha solução é usar 2 URIs diferentes para o mesmo serviço, em seguida, usar um comportamento ponto final para definir o formato de resposta de saída padrão. Você pode descobrir mais no este questão, que também aborda a pureza conceitual pergunta: devemos estar usando atributos de contrato para especificar as propriedades que fazem parte do protocolo de rede? Acho tomada de Marc Gravell sobre esta questão é válido por si só, mas não é consistente o conceito original do WCF, em que os contratos devem ser captada longe da pilha de protocolos. Mas comportamentos de ponto final não vai deixar você especificar todos os atributos relacionados descanso, você terá que usar os atributos para modelos URI e formato de entrada.

poderia descansar foram implementadas de forma diferente? Apesar dos designers da WCF fez um excelente trabalho de projetar uma estrutura genérica, eu não acho que eles viram RESTO vinda. Algumas coisas, como o modelo URI, realmente parecem pertencer com o contrato.

Chega de conversa! Aqui está o código. Primeiro o arquivo web.config. É aqui que a mágica acontece. Note que estou usando WCF activação baseado 4 configuração neste exemplo, mas você também pode fazer a mesma coisa por ter 2 arquivos SVC para representar os 2 URIs.

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="StackOverflow.QuoteOfTheDayAsJson">
        <endpoint binding="webHttpBinding" contract="StackOverflow.IQuoteOfTheDay" 
                  behaviorConfiguration="jsonBehavior" />
      </service>
      <service name="StackOverflow.QuoteOfTheDayAsPox">
        <endpoint binding="webHttpBinding" contract="StackOverflow.IQuoteOfTheDay" 
                  behaviorConfiguration="poxBehavior" />
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="jsonBehavior">
          <webHttp defaultOutgoingResponseFormat="Json" />
        </behavior>
        <behavior name="poxBehavior">
          <webHttp defaultOutgoingResponseFormat="Xml"/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="false">
      <serviceActivations>
        <add relativeAddress="QuoteOfTheDayJson.svc" 
             service="StackOverflow.QuoteOfTheDayAsJson"/>
        <add relativeAddress="QuoteOfTheDayPox.svc" 
             service="StackOverflow.QuoteOfTheDayAsPox"/>
      </serviceActivations>
    </serviceHostingEnvironment>
  </system.serviceModel>
</configuration>

E aqui está o código, incluindo contrato de serviço, implementação do serviço, e os aliases do tipo que são necessárias para fazer este trabalho:

namespace StackOverflow
{
    [DataContract]
    public class Quotation
    {
        [DataMember]
        public string Text { get; set; }

        [DataMember]
        public string Author { get; set; }
    }

    [ServiceContract]
    public interface IQuoteOfTheDay
    {
        [OperationContract]
        [WebInvoke(Method="GET", UriTemplate="GetTodaysQuote")]
        Quotation GetTodaysQuote();
    }

    public class QuoteOfTheDayImp : IQuoteOfTheDay
    {
        public Quotation GetTodaysQuote()
        {
            return new Quotation()
            {
                Text = "Sometimes it's better to appologize for not asking permission",
                Author = "Admiral Grace Murray Hopper"
            };
        }
    }

    /// <summary>
    /// A type alias used for json activation
    /// </summary>
    public class QuoteOfTheDayAsJson : QuoteOfTheDayImp 
    {}

    /// <summary>
    /// A type alias used for pox activation
    /// </summary>
    public class QuoteOfTheDayAsPox : QuoteOfTheDayImp
    {}
}

Se não fosse para a necessidade dos aliases tipo, eu diria que esta é uma solução completa. É uma solução completa se você não quer para suportar múltiplos formatos simultaneamente. Esta é superior à solução contrato múltipla no respeito que, uma vez que existe apenas um contrato, você não precisa manter os 2 contratos em sincronia.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top