Sto riscontrando problemi nel tentativo di utilizzare un servizio semplice con WCF. Tutto è andato bene finora, tranne quando si tratta di implementare parametri di stringa di query opzionali. L'interfaccia sembra un po 'come questo:Consumo del servizio REST con WCF - Parametri facoltativi di QueryString?
[ServiceContract]
[XmlSerializerFormat]
public interface IApi
{
[OperationContract]
[WebGet(UriTemplate = "/url/{param}?top={top}&first={first}")]
object GetStuff(string param, int top, DateTime first);
}
Allora questo è consumato con la creazione di una classe che eredita ClientBase<IApi>
. Ho provato un paio di modi per rendere i parametri opzionali:
1) Verificare i parametri annullabili
Ciò non ha funzionato. Ricevo un messaggio dal QueryStringConverter
come un'altra domanda ha chiesto: Can a WCF service contract have a nullable input parameter?
2) Uno dei parametri alla fine dell'URL
Così, ho pensato di cambiare l'UriTemplate per essere più generico, costruendo la query stringa e passandola come parametro. Anche questo non sembra funzionare, dato che il valore passato viene codificato in modo tale da non essere riconosciuto come una querystring dal server.
Esempio:
[WebGet(UriTemplate = "/url/{query}")]
3) Hackish Soluzione
L'unico modo che ho trovato finora di ottenere questo al lavoro è quello di cambiare tutti i parametri di stringhe e NULL di sembrano essere consentito Qui.
Esempio:
[WebGet(UriTemplate = "/url/{param}?top={top}&first={first}")]
object GetStuff(string param, string top, string first);
Il consumo di questa interfaccia ancora accetta il tipo di variabile corretto, ma ToString
viene utilizzato. I parametri della stringa di query appaiono ancora nella richiesta effettiva.
Quindi, c'è un modo quando consuma un servizio REST utilizzando WCF, per rendere facoltativi i parametri della stringa di query?
UPDATE - Come è stato fissato
Il consiglio di creare un servizio di comportamento è stata presa. Questo eredita da WebHttpBehaviour
. Sembra come segue:
public class Api : ClientBase<IApi>
{
public Api() : base("Binding")
{
Endpoint.Behaviors.Add(new NullableWebHttpBehavior());
}
}
Il NullableWebHttpBehavior
si possono trovare presso la seguente questione StackOverflow: Can a WCF service contract have a nullable input parameter?. L'unico problema era, ConvertValueToString
non era sovraccarico, così ho montata una veloce up:
public override string ConvertValueToString(object parameter, Type parameterType)
{
var underlyingType = Nullable.GetUnderlyingType(parameterType);
// Handle nullable types
if (underlyingType != null)
{
var asString = parameter.ToString();
if (string.IsNullOrEmpty(asString))
{
return null;
}
return base.ConvertValueToString(parameter, underlyingType);
}
return base.ConvertValueToString(parameter, parameterType);
}
Questo può non essere perfetto, ma sembra funzionare come previsto.
questo va a mostrare quanto wcf fa schifo. è incredibile quanti cerchi devi saltare per elaborare una cosa così semplice – jere
@jere d'accordo, è deludente. –
Concordato che wcf è estremamente complesso per la creazione di applicazioni di tipo rest-style. Il problema che wcf cerca di risolvere è rendere i servizi visualizzabili su diversi protocolli (tcp, msmq e http) e il resto è per sua natura legato a http. Quindi potresti obiettare che wcf è la scelta sbagliata per l'implementazione dei servizi di riposo. – faester