在asmx服务方法中使用可空参数导致其他方法失败

15

为了复现我所看到的问题,请使用VS2010创建一个空网站,并添加一个带有代码后台的Web服务(asmx)。

使用以下代码,两个Web方法均可以成功调用:

[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";
    }
}

现在,如果我将方法2的参数更改为可空类型,它就可以正常工作,但这会导致方法1失败...

[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";
    }
}

如果在调用服务时缺少参数,将会出现一个我之前见过的错误:

System.IndexOutOfRangeException:索引超出了数组边界。 在 System.Web.Services.Protocols.HttpServerType..ctor(Type type) 中 at System.Web.Services.Protocols.HttpServerProtocol.Initialize() 在 System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)

此外,只有当第一个方法返回 void 时,才会出现问题,因此这样也可以正常工作:

[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";
    }
}

这里发生了什么,有任何想法吗?这在使用3.5和4.0作为目标框架时都发生了。

编辑:提前防止进一步的回答/评论...我不寻求关于最佳实践、替代解决方案、asmx在服务景观中的位置、wcf等方面的建议。这是在调试一个我没有编写并且已经被修复的旧应用程序中遇到的问题,我有兴趣找出我在这里概述的特定行为的原因。


2
ASMX是一项传统技术,不应用于新开发。WCF应该用于所有新的Web服务客户端和服务器的开发。一个提示:微软已经在MSDN上停止了ASMX论坛。 - John Saunders
1
谢谢,但这不是新开发的应用程序,它是一个非常旧的应用程序。我将其简化为一个简单的示例来说明问题。 - heisenberg
听起来很像这个:http://www.therebelheart.com/blog/2007/6/6/5-hours-later-and-hello-world-saves-the-day.html - StuartLC
ASP.NET Web Services(ASMX)在.NET 2.0中引入了对可空类型的支持。在.NET 1.0和1.1中,框架不支持值类型的xsi:nil,因为我们知道,值类型不能设置为null。来源:http://adrianba.net/archive/2005/03/02/5aa86125c57a40c3b3a22662304beb16.aspx - David Negron
1
太棒了!我卡在这个问题上很久了,从来没有想到在类的顶部添加一个非 void 返回方法。 - Ripside
显示剩余6条评论
4个回答

1
我尝试了你的代码,它能正常工作。虽然调试不起作用,会产生错误。
我认为这是因为 Nullable int 不是原始类型。从服务的 WSDL 描述中可以看到:“测试表单仅适用于具有原始类型参数的方法”。
我认为你面临的问题并不是由于 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";
    }
}

网站代码:

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

1

@heisenberg,你是否从调用Web方法的应用程序中传递了空值.. 我尝试的示例在vs2010上运行良好。以下是我尝试的代码。

示例代码:

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

服务 ASMX 代码

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

    }
}

0

这可能是因为您正在尝试将相同的X发送到两种方法中,尽管它们不接受相同的类型?

因为其中一个是可空的,而另一个则不是。


-1

在您的解决方案中,使用Nullable (?)是必要的吗?我认为您可以实现一个非常简单的逻辑,例如:"如果我收到一个空字符串,那么我就有一个Null值;如果我收到一个"Null"字符串值,那么我需要使用一个Null对象",并且在未来考虑使用带有Nullable-?方法的WCF。

另一方面,我建议您将所有的void方法更改为带有单词"ok"的字符串值。我认为"请求应该有响应"。


好的。https://dev59.com/dVXTa4cB1Zd3GeqPzTR4 - CharlyKno

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接