为所有字符串类型方法生成消息协定

时间:2017-09-25 14:18:54

标签: c# asp.net .net web-services soap

我正在使用 Visual Studio 15.3.5 ,我正在尝试创建一个Web服务。我选择了 ASP.NET Web应用程序(.Net Framework)目标框架:.Net framework 4.6.1 。我在 WebServiceMain.asmx 文件中有一个非常简单的代码:

using System.Web.Services;

namespace WebServiceServer
{
    [System.SerializableAttribute()]
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]

    public class WebServiceMain : System.Web.Services.WebService
    {
        [WebMethod]
        public int getSum(int a, int b)
        {
            return (a + b);
        }

        [WebMethod]
        public string getName(string code)
        {
            return code;
        }
    }
}

我还有一个不同的项目作为客户端。我添加了一项服务(让我们称之为 ServiceReference1 )。我已更新服务引用,这是生成代码的一部分:

namespace WebServiceClient.ServiceReference1 {


    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
    [System.ServiceModel.ServiceContractAttribute(ConfigurationName="ServiceReference1.WebServiceMainSoap")]
    public interface WebServiceMainSoap {

        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/getSum", ReplyAction="*")]
        int getSum(int a, int b);

        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/getSum", ReplyAction="*")]
        System.Threading.Tasks.Task<int> getSumAsync(int a, int b);

        // CODEGEN: Generating message contract since element name code from namespace http://tempuri.org/ is not marked nillable
        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/getName", ReplyAction="*")]
        WebServiceClient.ServiceReference1.getNameResponse getName(WebServiceClient.ServiceReference1.getNameRequest request);

        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/getName", ReplyAction="*")]
        System.Threading.Tasks.Task<WebServiceClient.ServiceReference1.getNameResponse> getNameAsync(WebServiceClient.ServiceReference1.getNameRequest request);
    }

    // etc.
}

还在客户 main()中写道:

ServiceReference1.WebServiceMainSoap clientReference = new ServiceReference1.WebServiceMainSoapClient();
Console.WriteLine(clientReference.getSum(2, 6));
Console.WriteLine(clientReference.getName("T100"));

问题是返回字符串的任何方法在客户端都没有正确格式化。例如,clientReference.getSum(2, 6)工作正常但clientReference.getName("T100")没有,我得到:

  

CS1061&#39; WebServiceMainSoap&#39;不包含的定义   &#39; getModuleName&#39;没有扩展方法&#39; getModuleName&#39;接受一个   类型&#39; WebServiceMainSoap&#39;的第一个参数可以找到(是你   缺少using指令或程序集引用?)

     

CS1503参数1:无法转换为&#39;字符串&#39; to&#39; WebServiceClient.ServiceReference1.getNameRequest

在生成的代码中,我看到了这条评论:// CODEGEN: Generating message contract since element name code from namespace http://tempuri.org/ is not marked nillable所以我假设我需要在某处写nillable,但我尝试了Hibernate Docssomething like in here和{{3}但它不起作用,因为WSDL文件只在客户端应用程序中找到,但如果我更新服务引用则会被覆盖。

我想要这样的东西来解决(当然,这是无效的):

[WebMethod(nillable = true)]
public string getName(string code)
{
    return code;
}

1 个答案:

答案 0 :(得分:1)

默认情况下, ASMX 使用 HttpPost 方法而不是HttpGet。如果您想允许HttpGet,则需要[ScriptMethod(UseHttpGet = true)]

FYI :如果您想将字符串作为参数传递,我强烈建议您不要使用可能导致网址无效的HttpGet。

[WebMethod]
[ScriptMethod(UseHttpGet = true)]
public int getSum(int a, int b)
{
    return (a + b);
}

[WebMethod]
public string getName(string code)
{
    return code;
}

另一件事是因为你想要返回字符串,服务需要getNameRequest个对象,并返回getNameResponse个对象。

getNameResponse response = 
   clientReference.getName(new getNameRequest(new getNameRequestBody("T100")));
Console.WriteLine(response.Body.getNameResult);