Condividi tramite


Formattazione HTTP Web WCF

Il modello di programmazione HTTP Web WCF consente di determinare in modo dinamico il formato migliore per un'operazione del servizio in cui restituire la risposta. Sono supportati due metodi per determinare un formato appropriato: automatico ed esplicito.

Formattazione automatica

Se abilitata, la formattazione automatica sceglie il formato migliore in cui restituire la risposta. Determina il formato migliore controllando quanto segue, in ordine:

  1. Tipi di media nell'intestazione Accept del messaggio di richiesta.

  2. Tipo di contenuto del messaggio di richiesta.

  3. Impostazione di formato predefinita nell'operazione.

  4. Impostazione di formato predefinita in WebHttpBehavior.

Se il messaggio di richiesta contiene un'intestazione Accept, l'infrastruttura wcf (Windows Communication Foundation) cerca un tipo supportato. Se l'intestazione Accept specifica le priorità per i relativi tipi di supporti, vengono rispettate. Se nell'intestazione Accept non viene trovato alcun formato appropriato, viene usato il tipo di contenuto del messaggio di richiesta. Se non viene specificato alcun tipo di contenuto appropriato, viene utilizzata l'impostazione di formato predefinita per l'operazione. Il formato predefinito viene impostato con il ResponseFormat parametro degli WebGetAttribute attributi e WebInvokeAttribute . Se non viene specificato alcun formato predefinito nell'operazione, viene utilizzato il valore della DefaultOutgoingResponseFormat proprietà . La formattazione automatica si basa sulla AutomaticFormatSelectionEnabled proprietà . Quando questa proprietà è impostata su true, l'infrastruttura WCF determina il formato migliore da usare. La selezione automatica del formato è disabilitata per impostazione predefinita per la compatibilità con le versioni precedenti. La selezione automatica del formato può essere abilitata a livello di codice o tramite la configurazione. Nell'esempio seguente viene illustrato come abilitare la selezione automatica del formato nel codice.

// This code assumes the service name is MyService and the service contract is IMyContract
Uri baseAddress = new Uri("http://localhost:8000");  
  
WebServiceHost host = new WebServiceHost(typeof(MyService), baseAddress)  
try  
{  
   ServiceEndpoint sep = host.AddServiceEndpoint(typeof(IMyContract), new WebHttpBinding(), "");  
   // Check it see if the WebHttpBehavior already exists  
   WebHttpBehavior whb = sep.Behaviors.Find<WebHttpBehavior>();  
  
   if (whb != null)  
   {  
      whb.AutomaticFormatSelectionEnabled = true;  
   }  
   else  
   {  
      WebHttpBehavior webBehavior = new WebHttpBehavior();  
      webBehavior.AutomaticFormatSelectionEnabled = true;  
      sep.Behaviors.Add(webBehavior);  
   }  
         // Open host to start listening for messages  
   host.Open();
  
  // ...  
}  
  catch(CommunicationException ex)  
  {  
     Console.WriteLine("An exception occurred: " + ex.Message());  
  }  

La formattazione automatica può essere abilitata anche tramite la configurazione. È possibile impostare la AutomaticFormatSelectionEnabled proprietà direttamente su WebHttpBehavior o utilizzando .WebHttpEndpoint Nell'esempio seguente viene illustrato come abilitare la selezione automatica del formato in WebHttpBehavior.

<system.serviceModel>  
  <behaviors>  
    <endpointBehaviors>  
      <behavior>  
        <webHttp automaticFormatSelectionEnabled="true" />  
      </behavior>  
    </endpointBehaviors>  
  </behaviors>  
  <standardEndpoints>  
    <webHttpEndpoint>  
      <!-- the "" standard endpoint is used by WebServiceHost for auto creating a web endpoint. -->  
      <standardEndpoint name="" helpEnabled="true" />  
    </webHttpEndpoint>  
  </standardEndpoints>  
</system.serviceModel>  

Nell'esempio seguente viene illustrato come abilitare la selezione automatica del formato usando WebHttpEndpoint.

<system.serviceModel>  
    <standardEndpoints>  
      <webHttpEndpoint>  
        <!-- the "" standard endpoint is used by WebServiceHost for auto creating a web endpoint. -->  
        <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"  />  
      </webHttpEndpoint>  
    </standardEndpoints>  
  </system.serviceModel>  

Formattazione esplicita

Come suggerisce il nome, nella formattazione esplicita lo sviluppatore determina il formato migliore da usare all'interno del codice dell'operazione. Se il formato migliore è XML o JSON, lo sviluppatore imposta Format su Xml o Json. Se la Format proprietà non è impostata in modo esplicito, viene usato il formato predefinito dell'operazione.

Nell'esempio seguente viene controllato il parametro della stringa di query di formato per determinare quale formato utilizzare. Se è stato specificato, imposta il formato dell'operazione usando Format.

public class Service : IService  
{  
    [WebGet]  
     public string EchoWithGet(string s)  
    {  
        // if a format query string parameter has been specified, set the response format to that. If no such
        // query string parameter exists the Accept header will be used
        string formatQueryStringValue = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters["format"];  
        if (!string.IsNullOrEmpty(formatQueryStringValue))  
        {  
            if (formatQueryStringValue.Equals("xml", System.StringComparison.OrdinalIgnoreCase))  
            {
                WebOperationContext.Current.OutgoingResponse.Format = WebMessageFormat.Xml;
            }
            else if (formatQueryStringValue.Equals("json", System.StringComparison.OrdinalIgnoreCase))  
            {  
                WebOperationContext.Current.OutgoingResponse.Format = WebMessageFormat.Json;  
            }  
            else  
            {  
                throw new WebFaultException<string>($"Unsupported format '{formatQueryStringValue}'",   HttpStatusCode.BadRequest);
            }  
        }  
        return "You said " + s;  
    }  

Se è necessario supportare formati diversi da XML o JSON, definire l'operazione in modo che abbia un tipo restituito di Message. Nel codice dell'operazione determinare il formato appropriato da usare e quindi creare un Message oggetto usando uno dei metodi seguenti:

  • WebOperationContext.CreateAtom10Response

  • WebOperationContext.CreateJsonResponse

  • WebOperationContext.CreateStreamResponse

  • WebOperationContext.CreateTextResponse

  • WebOperationContext.CreateXmlResponse

Ognuno di questi metodi accetta contenuto e crea un messaggio con il formato appropriato. Il WebOperationContext.Current.IncomingRequest.GetAcceptHeaderElements metodo può essere usato per ottenere un elenco di formati preferiti dal client in ordine di preferenza decrescente. L'esempio seguente illustra come usare WebOperationContext.Current.IncomingRequest.GetAcceptHeaderElements per determinare il formato da usare e quindi usa il metodo di risposta di creazione appropriato per creare il messaggio di risposta.

public class Service : IService  
{  
    public Message EchoListWithGet(string list)  
    {  
        List<string> returnList = new List<string>(list.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries));  
        IList<ContentType> acceptHeaderElements = WebOperationContext.Current.IncomingRequest.GetAcceptHeaderElements();  
        for (int x = 0; x < acceptHeaderElements.Count; x++)  
        {  
            string normalizedMediaType = acceptHeaderElements[x].MediaType.ToLowerInvariant();  
            switch (normalizedMediaType)  
            {  
                case "image/jpeg": return CreateJpegResponse(returnList);  
                case "application/xhtml+xml": return CreateXhtmlResponse(returnList);  
                case "application/atom+xml": return CreateAtom10Response(returnList);  
                case "application/xml": return CreateXmlResponse(returnList);  
                case "application/json": return CreateJsonResponse(returnList);  
          }  
    }  
  
    // Default response format is XML  
    return CreateXmlResponse(returnList);  
    }  
}  

Vedere anche