1

I'm using Visual Studio 15.3.5 and I'm trying to create a Web Service. I have selected ASP.NET Web Application (.Net Framework) with target framework: .Net framework 4.6.1. I have a pretty simple code in WebServiceMain.asmx file:

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

I also have a different project that works as a client. I have added a service (let's call it ServiceReference1). I have updated service references and this is the part of a generated code:

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.
}

And also in client main() I have written:

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

The problem is that any method that returns string is not formatted properly in client side. For example, clientReference.getSum(2, 6) works fine but clientReference.getName("T100") does not and I get:

CS1061 'WebServiceMainSoap' does not contain a definition for 'getModuleName' and no extension method 'getModuleName' accepting a first argument of type 'WebServiceMainSoap' could be found (are you missing a using directive or an assembly reference?)

CS1503 Argument 1: cannot convert from 'string' to 'WebServiceClient.ServiceReference1.getNameRequest

In generated code I see this comment: // CODEGEN: Generating message contract since element name code from namespace http://tempuri.org/ is not marked nillable so I assume I need to write nillable somewhere, but I have tried something like in here, in here and searched in here but it doesn't work because WSDL file is found only in client application but is being overwritten if I update service references.

I would like something like this to solve (which, of course, is not valid):

[WebMethod(nillable = true)]
public string getName(string code)
{
    return code;
}
Gynteniuxas
  • 7,035
  • 18
  • 38
  • 54

1 Answers1

1

By default, ASMX uses HttpPost method instead of HttpGet. If you want to allow HttpGet, you will need [ScriptMethod(UseHttpGet = true)].

FYI: If you want to pass string as parameter, I highly suggest not to use HttpGet which could cause URL invalid.

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

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

Another thing is since you want to return string, the service requires getNameRequest object, and returns getNameResponse object.

getNameResponse response = 
   clientReference.getName(new getNameRequest(new getNameRequestBody("T100")));
Console.WriteLine(response.Body.getNameResult);
Win
  • 61,100
  • 13
  • 102
  • 181
  • 1
    Wow, that works... But why all `public string` methods require such approach while `public int` (and similar) can be written as simply as `clientReference.Add(2, 8)`? – Gynteniuxas Sep 25 '17 at 15:25