【问题标题】:Nullable param in asmx service method causes other method to failasmx 服务方法中的可空参数导致其他方法失败
【发布时间】:2013-03-24 06:15:49
【问题描述】:

要重现我看到的问题,使用 VS2010,创建一个空网站并添加一个带有代码隐藏的 Web 服务 (asmx)。

使用如下代码,两个webmethods都可以成功调用:

[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(类型 类型)在 System.Web.Services.Protocols.HttpServerProtocol.Initialize() 在 System.Web.Services.Protocols.ServerProtocolFactory.Create(类型类型, HttpContext 上下文,HttpRequest 请求,HttpResponse 响应, 布尔值&中止处理)

此外,只有在第一个方法返回 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 作为目标框架时。

编辑:只是为了抢占这些方面的进一步答案/cmets...我不是在寻找关于最佳实践、替代解决方案、asmx 在服务领域中的位置、wcf 等方面的建议。这是我来的在调试旧版应用程序中的问题时,该问题不是我编写的,并且已经修复,我有兴趣找出我在此处概述的特定行为的原因。

【问题讨论】:

  • ASMX 是一项遗留技术,不应用于新开发。 WCF 应该用于 Web 服务客户端和服务器的所有新开发。一个提示:微软已经在 MSDN 上停用了ASMX Forum
  • 另外,我不相信 ASMX 支持可为空的参数。
  • 谢谢,但这不是新开发,它是一个非常古老的应用程序。我将其提炼成一个简单的示例来说明问题。
  • 可空参数在使用它的方法上运行良好。
  • 精彩的发现。我被困在这个问题上太久了,我从来没有想过在类的顶部添加一个非 void 返回方法。

标签: c# asp.net asmx


【解决方案1】:

@heisenberg,你是从调用 web 方法的应用程序传递 null 吗? 我尝试的示例在 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)
    {

    }
}

【讨论】:

    【解决方案2】:

    我尝试了您的代码,它可以正常工作。虽然调试不工作,但产生错误。

    我认为这是因为 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);
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      这可能发生的原因可能是您尝试将相同的 X 发送给这两种方法,尽管它们没有采用相同的类型?

      因为一个可以为空,而另一个不能。

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-12-20
        • 1970-01-01
        • 1970-01-01
        • 2013-08-24
        • 1970-01-01
        • 1970-01-01
        • 2018-03-30
        相关资源
        最近更新 更多