.Net WebServices and out/ref WebMethod arguments

Maybe this will help:

http://kbalertz.com/322624/Proxy-Class-First-Parameter-Service-Method-Returns-Return-Value-Reference.aspx

My favorite part is:

STATUS

This behavior is by design.


I don't know what the protocol is for providing answers to your own questions, but the article referenced by Steven Behnke provided some clues for me to deduce a solution to this bizarre situation. And rather than leave everyone else to figure out what the implications are, I thought I share my findings.

So, consider the following webmethods defined in my 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";
}

Now according to the document, the first parameter defined as Out, if the method returns void, then the first parameter is automatically used as the return parameter. So I would access each of my methods as follows:

Method1:

public string Method1() {}

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

Method2:

public void Method2(out string strVal1) {}

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

So you access them both in exactly the same manner, which is extremely confusing. Who on Earth would figure that out without having been told that by someone else? It is beyond my comprehension, how this could be a good idea.

Method3:

public void Method3(out string strVal1, out string strVal) {}

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

Method4:

public string Method4(out string strVal1, out string strVal2) {}

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);

So as you notice - if the method signature doesn't provide a return value [that is returns void], then the first param becomes the return value. If it already provides a return value, then it doesn't.

This can be extremely confusing for someone that hasn't come across that document. Many thanks for providing that link Steven - I really appreciate it.

To whomever decided that design pattern was a good idea to be written into the .NET Framework - I can't think what would've posessed you to think that was a good idea. I really dislike you quite intensely after all that.

ADDENDUM:

What I only just realised is that to add to the confusion, if you use ref instead of out then you don't do this, you'd treat the WebMethods exactly as you would have if you'd used them to call a regular method inside your application:

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

Now to call that you'd use:

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

This inconsistency is mindboggling. The fact, that it is by design, is incomprehensible to me.