2008-12-18 13 views
11

He recibido documentación de uno de nuestros proveedores para un servicio web que están publicando y son muy específicos de que en uno de sus métodos web un argumento tiene el modificador de salida (? no estoy seguro si eso es el descriptor de la derecha), por ejemplo, considere la siguiente WebMethod firma:WebServices .Net y argumentos out/ref WebMethod

[WebMethod] 
public void HelloWorld(out string strVal) 
{ 
    strVal = "Hello World"; 
} 

[Obviamente, el método actual no es un método Hello World]

Ahora, yo nunca había considerado el diseño de una WebMethod con un argumento out/ref y me hizo preguntarme por qué lo habrían usado.

Intentando entender una aplicación para esta decisión de diseño, lancé un prototipo junto con algunos métodos web de estilo Hello World básicos ... uno con un único argumento de cadena de salida, uno con dos argumentos de cadena y uno que no recibe cualquier argumento, pero devuelve una cadena.

Al tratar de hacer referencia a mis métodos web desde una aplicación por separado, noto que tengo que acceder al método con el argumento cadena única como si hubiera definido el método para dar salida a la cadena de manera que el cliente está preocupado:

public string HelloWorld1() 
{ 
    return "Hello World"; 
} 

y

public void HelloWorld2(out string strVal) 
{ 
    strVal = "Hello World"; 
} 

son exactamente los mismos ... en que tengo que hacer referencia a ambos como tales [donde x es sustituido por el método correcto]:

string val = HelloWorldX(); 

Habiendo intentado hacer referencia a los métodos en la forma en que iba a acceder a ellos si no había métodos web [como así]:

string val = string.Empty; 
MyService1.HelloWorld(out val); 
Console.WriteLine(val); 

lo que provoca un error de compilación que indica que no hay argumentos de los métodos de entrada aceptan 1 . ¿Porqué es eso? Obviamente, hay un método web que acepta un argumento: lo estoy viendo [HelloWorld2].

Al examinar las respuestas de SOAP, noto que el contenido de la respuesta de HelloWorld1 es:

<HelloWorld1Response xmlns="http://tempuri.org/"> 
    <HelloWorld1Result>string</HelloWorld1Result> 
</HelloWorld1Response> 

Y HelloWorld2 es

<HelloWorld2Response xmlns="http://tempuri.org/"> 
    <strVal>string</strVal> 
</HelloWorld2Response> 

Yendo un paso más allá que pensaba, lo que si tengo 2 argumentos de ref ...

public void HelloWorld3(out string strVal1, out string strVal2) 
{ 
    strVal1 = "Hello World"; 
    strVal2 = "Hello World Again!"; 
} 

Esto genera el contenido de SOAP:

<HelloWorld3Response xmlns="http://tempuri.org/"> 
    <strVal1>string</strVal1> 
    <strVal2>string</strVal2> 
</HelloWorld3Response> 

pensé justo lo suficiente, por lo que teóricamente [proporcionar puedo encontrar una manera de pasar los argumentos/ref a webMethods] eso significa que sólo puede pasar en dos argumentos que se pueden configurar mediante el método, pero cuando hago esto:

string val1 = string.Empty; 
string val2 = string.Empty; 
MyService1.HelloWorld3(out val1,out val2); 
Console.WriteLine(val1); 
Console.WriteLine(val2); 

que debería obtener el mismo error de compilación vi cuando traté de hacer referencia a la HelloWorld2 esta manera. Con la obvia excepción de que se queja de 2 argumentos en lugar de 1 [y de hecho obtengo la misma excepción, lo probé].

  • ¿Qué ofrece?
  • ¿Hay alguna razón o una forma de usar los argumentos out/ref en WebMethods que me faltan?
  • Si lo hay, ¿cómo hago referencia a WebMethods con múltiples argumentos de salida/ref?

Respuesta

15

Er ... No sé cual es el protocolo para proporcionar respuestas a sus propias preguntas, pero el artículo de referencia por Steven Behnke proporciona algunas pistas para mí para deducir una solución a esta extraña situación, y en lugar de dejar que los demás averiguar cuáles son las implicaciones, pensé que me gustaría compartir mis hallazgos ...

lo tanto, considerar los siguientes webmethods definidos en mi WebService

[WebMethod] 
public string Method1() 
{ 
    return "This is my return value"; 
} 

[WebMethod] 
public void Method2(out string strVal1) 
{ 
    strVal1 = "This is my value passed as an output"; 
    //No return value 
} 

[WebMethod] 
public void Method3(out string strVal1, out string strVal2) 
{ 
    strVal1 = "This is my strVal1 value passed as an output"; 
    strVal2 = "This is my strVal2 value passed as an output"; 
    //No return value 
} 

[WebMethod] 
public string Method4(out string strVal1, out string strVal2) 
{ 
    strVal1 = "This is my strVal1 value passed as an output"; 
    strVal2 = "This is my strVal2 value passed as an output"; 
    return "This is my return value"; 
} 

Ahora ... de acuerdo con el documento, el primer parámetro definido como Out, si el método devuelve vacío, entonces el primer par ameter se usa automáticamente como el parámetro de retorno. Así que me gustaría tener acceso a cada uno de mis métodos de la siguiente manera:

Método1: public String Método1() {}

var str = svc.Method1(); 
Console.WriteLine(str); 

Método 2: public void Método 2 (de un total de cadena strVal1) {}

var str = svc.Method2(); 
Console.WriteLine(str); 

Entonces accedes a ambos de la misma manera ... lo cual es extremadamente confuso. ¿Quién demonios se daría cuenta de eso sin que alguien más se lo haya dicho? Está más allá de mi comprensión de cómo esto podría ser una buena idea ...

metodo3: public void metodo3 (de un total de cadena strVal1, fuera strval cadena) {}

var str2 = String.Empty; 
var str1 = svc.Method3(out str2); 
Console.WriteLine(str1); 
Console.WriteLine(str2); 

método 4: public String método 4 (de un total de cadena strVal1 , fuera strVal2 cadena) {}

var str1 = String.Empty; 
var str2 = String.Empty; 
var str3 = svc.Method4(out str1, out str2); 
Console.WriteLine(str1); 
Console.WriteLine(str2); 
Console.WriteLine(str3); 

Así como usted nota - si la firma del método no proporciona un valor de retorno [es decir] rendimientos nulos, entonces el primer parámetro se convierte en el valor de retorno. Si ya proporciona un valor de retorno, entonces no es así.

Esto puede ser extremadamente confuso para alguien que no ha encontrado ese documento. Muchas gracias por proporcionar ese enlace Steven - Realmente lo aprecio.

... y para quien decidió que el patrón de diseño era una buena idea para ser escrito en el .NET Framework - No puedo pensar qué hubiera sido suficiente para pensar que era una buena idea ... Realmente te desagrada bastante intensamente después de todo eso.

Adición:

lo que sólo he dado cuenta es que al aumentar la confusión, si se utiliza ref en lugar de salir entonces no hace esto, usted' d tratar webMethods exactamente como usted tendría si hubiera utilizado ellos para llamar a un método regular dentro de su aplicación:

[WebMethod()] 
public void Method3(ref string strVal1, ref string strVal2) 
{ 
    strVal1 = "First argument return value"; 
    strVal2 = "Second argument return value"; 
} 

Ahora para llamar a que tendrá que utilizar:

string val1 = String.Empty; 
string val2 = String.Empty; 
svc.Method3(ref val1, ref val2); 
Console.WriteLine(val1); 
Console.WriteLine(val2); 

Esta inconsistencia se mindboggling ... el hecho de que es por diseño es incomprensible para mí.

+0

Cuando llegue a la reputación de 2000, creo que el protocolo correcto sería editar la respuesta de Steven Behnke ... por intrusivo que pueda parecer. Pero es un buen trabajo publicar tu resumen. +1 –

+0

@John: Gracias, lo tendré en cuenta para futuras publicaciones – BenAlabaster

Cuestiones relacionadas