Tengo problemas para intentar consumir un servicio simple usando WCF. Todo ha ido bien hasta ahora, excepto cuando se trata de implementar parámetros de cadena de consulta opcionales. La interfaz se ve un poco como esto:¿Consumo de servicio REST con WCF - Parámetros de Querystring opcionales?
[ServiceContract]
[XmlSerializerFormat]
public interface IApi
{
[OperationContract]
[WebGet(UriTemplate = "/url/{param}?top={top}&first={first}")]
object GetStuff(string param, int top, DateTime first);
}
Entonces este es consumido por la creación de una clase que hereda ClientBase<IApi>
. He intentado un par de maneras de hacer que los parámetros opcionales:
1) Hacer los parámetros nullable
Esto no funcionó. Me sale un mensaje de la QueryStringConverter
como otra cuestión ha preguntado: Can a WCF service contract have a nullable input parameter?
2) Un parámetro al final de la URL
lo tanto, pensé en cambiar el UriTemplate para ser más genérico, la construcción de la consulta cadena y pasándolo como un parámetro. Esto tampoco pareció funcionar, ya que el valor pasado se codifica de tal manera que el servidor no lo reconoce como una cadena de consulta.
Ejemplo:
[WebGet(UriTemplate = "/url/{query}")]
3) hacker Solución
La única manera que he encontrado hasta el momento de conseguir que esto funcione es cambiar todos los parámetros en cadenas, y NULL de parecen estar permitido aquí.
Ejemplo:
[WebGet(UriTemplate = "/url/{param}?top={top}&first={first}")]
object GetStuff(string param, string top, string first);
El consumo de esta interfaz todavía acepta el tipo de variable correcto, pero ToString
se utiliza. Los parámetros de cadena de consulta siguen apareciendo en la solicitud real.
Entonces, ¿hay alguna manera cuando consume un servicio REST usando WCF, para hacer que los parámetros de cadena de consulta sean opcionales?
ACTUALIZACIÓN - ¿Cómo se fija
El consejo para crear un comportamiento en servicio fue tomada. Esto hereda de WebHttpBehaviour
. Se ve de la siguiente manera:
public class Api : ClientBase<IApi>
{
public Api() : base("Binding")
{
Endpoint.Behaviors.Add(new NullableWebHttpBehavior());
}
}
El NullableWebHttpBehavior
se puede encontrar en la siguiente pregunta Stackoverflow: Can a WCF service contract have a nullable input parameter?. El único problema era, ConvertValueToString
no estaba sobrecargado, así que sacó una rápida un gol arriba:
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);
}
Esto puede no ser perfecto, pero parece que funciona según lo previsto.
esto va a mostrar cuánto wcf apesta. es increíble cuántos aros tienes que saltar para resolver algo tan simple – jere
@jere estuvo de acuerdo, es decepcionante. –
Estoy de acuerdo en que wcf es abiertamente complejo para crear aplicaciones de estilo de descanso. El problema que trata de resolver es hacer que los servicios sean visibles en diferentes protocolos (tcp, msmq y http) y el resto está vinculado por naturaleza a http. Entonces, podría argumentar que wcf es la opción incorrecta para implementar servicios de descanso. – faester