15

To recreate the issue I'm seeing, using VS2010, create an empty website and add a web service (asmx) with code-behind.

Using the following code, both webmethods can be invoked successfully:

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService {
    [WebMethod]
    public void Method1(int x) {
        // i'm good
    }
    [WebMethod]
    public string Method2(int x) {
        return "it worked";
    }
}

Now, if I change the parm on method 2 to a nullable type it works just fine, but it will make method 1 fail...

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService {
    [WebMethod]
    public void Method1(int x) {
        // no changes made to this method, but it no longer works
    }
    [WebMethod]
    public string Method2(int? x) {
        return "it worked";
    }
}

The resulting error is one that I've seen before if a param is missing when calling a service:

System.IndexOutOfRangeException: Index was outside the bounds of the array. at System.Web.Services.Protocols.HttpServerType..ctor(Type type) at System.Web.Services.Protocols.HttpServerProtocol.Initialize() at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)

Also, this only appears to break if the first method returns void, so this also works fine:

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService {
    [WebMethod]
    public string Method1(int x) {
        return "works again";
    }
    [WebMethod]
    public string Method2(int? x) {
        return "it worked";
    }
}

Any ideas what is going on here? This occurred using both 3.5 and 4.0 as the target framework.

edit: Just to pre-empt further answers/comments along these lines...I'm not looking for advice on best practices, alternate solutions, asmx's place in the service landscape, wcf etc. This is something which I came across while debugging an issue in a legacy app which I did not write and which has already been fixed, and I'm interested in finding out the cause of the specific behavior that I've outlined here.

heisenberg
  • 9,665
  • 1
  • 30
  • 38
  • 2
    ASMX is a legacy technology, and should not be used for new development. WCF should be used for all new development of web service clients and servers. One hint: Microsoft has retired the [ASMX Forum](http://social.msdn.microsoft.com/Forums/en-US/asmxandxml/threads) on MSDN. – John Saunders Apr 02 '13 at 19:45
  • Also, I don't believe that ASMX supports nullable parameters. – John Saunders Apr 02 '13 at 19:46
  • 1
    Thanks but this isn't new development, its a very old app. I distilled it into a simple sample to illustrate the issue. – heisenberg Apr 02 '13 at 19:46
  • The nullable param works fine on the method that uses it. – heisenberg Apr 02 '13 at 19:47
  • So, it's an old app, but you've now changed a parameter? – John Saunders Apr 02 '13 at 19:47
  • Its an old app, and a parameter was changed. – heisenberg Apr 02 '13 at 19:48
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/27425/discussion-between-kekekela-and-john-saunders) – heisenberg Apr 02 '13 at 19:50
  • Sounds similar to this : http://www.therebelheart.com/blog/2007/6/6/5-hours-later-and-hello-world-saves-the-day.html – StuartLC Sep 26 '13 at 16:02
  • ASP.NET Web Services (ASMX) in .NET 2.0 introduces support for nullable types. In .NET 1.0 and 1.1, the framework didn't support xsi:nil for value types because, as we know, value types can't be set to null. source: http://adrianba.net/archive/2005/03/02/5aa86125c57a40c3b3a22662304beb16.aspx – David Negron Sep 30 '13 at 19:59
  • "This occurred using both 3.5 and 4.0 as the target framework." – heisenberg Oct 01 '13 at 14:48
  • 1
    Brilliant discovery. I was stuck on this for way too long, it never would have occurred to me to add a non-void return method at the top of the class. – Ripside Oct 10 '16 at 21:06

4 Answers4

1

@heisenberg, are you passing null from the application which invokes the web method.. The sample that I tried works fine on vs2010. below it the code that I tried.

Sample Code:

 protected void Button1_Click(object sender, EventArgs e)
    {
        WebService1 objws = new WebService1();
        objws.voidMethod(5);
        Label1.Text = objws.HelloWorld(5);
    }

Service ASMX Code

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService1 : System.Web.Services.WebService
{
    [WebMethod]
    public string HelloWorld(int? x)
    {
        if (x != null)
        {
            return x.ToString();
        }
        return "Hello World";
    }

    [WebMethod]
    public void voidMethod(int x)
    {

    }
}
Venkatesh Ellur
  • 158
  • 1
  • 10
1

I tried your code and it is working. Although debugging is not working, producing error.

I think it is happening because Nullable int is not primitive type. See the description from WSDL of the service "The test form is only available for methods with primitive types as parameters".

I suppose issue you are facing is not because of Nullable int.

[WebService(Namespace = "http://tempuri.org/")]

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

[System.ComponentModel.ToolboxItem(false)]

public class WebService1 : System.Web.Services.WebService
{
    [WebMethod]
    public void Method1(int x)
    {
        // i'm good
    }
    [WebMethod]
    public string Method2(int? x)
    {
        return "it worked";
    }
}

Website code:

namespace Helper
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            ServiceReference1.WebService1SoapClient web = new ServiceReference1.WebService1SoapClient();
            web.Method1(5);

            string x = web.Method2(5);
        }
    }
}
Kahbazi
  • 14,331
  • 3
  • 45
  • 76
0

it may happen cause may be you are trying to send the same X to both of the methods though they are not taking the same type?

cause one is nullable and another one is not.

-1

Is necessary the use of the Nullable (?) in your solution? I think that you can implement a very simple logic like: "If I receive an empty String then I have a Null value or if I receive a "Null" string value then I need to use a Null Object" and In the future consider the usage of WCF with the Nullable-? approach.

On the other hand, I recommend you the change of all the void methods to a string value with the word "ok". I think that a "A request should have a response".

Jesse
  • 8,605
  • 7
  • 47
  • 57
CharlyKno
  • 11
  • 1
  • Ok. http://stackoverflow.com/questions/5301549/methods-with-nullable-types-not-working-in-asmx-web-service-using-get – CharlyKno Apr 03 '13 at 00:36