Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nullable param in asmx service method causes other method to fail

Tags:

c#

asp.net

asmx

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.

like image 295
heisenberg Avatar asked Apr 02 '13 19:04

heisenberg


2 Answers

@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)
    {

    }
}
like image 76
Venkatesh Ellur Avatar answered Sep 21 '22 00:09

Venkatesh Ellur


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);
        }
    }
}
like image 30
Soumitra Bhatt Avatar answered Sep 21 '22 00:09

Soumitra Bhatt