简体   繁体   中英

Can't use optional parameters when implementing an interface for a WCF

In my interface I have declared this.

[OperationContract]
[WebGet]
String GetStuff(String beep, String boop = "too lazy to type");

I implemented it as follows.

String GetStuff(String beep, String boop = "too lazy to type") { ... }

It compiles and uploads as my WCF service. However, when I used it as a web reference and try to execute the code below, I get the compiler whining and weeping about no method with signature of a single parameter. The last line is the problem.

How can I then be too lazy to type by default ?

ServiceClient client = new ServiceClient();
client.GetStuff("blobb", "not lazy");
client.GetStuff("blobb");

Simply: default arguments are not supported.

By design and with reason. We use C# to write WCF contracts but that's a notational trick. Not every C# language feature can be implemented in SOAP, REST or JSon.

You can try this, overloading the function.

[OperationContract]
MyResponse GetData(); 

[OperationContract(Name = "GetDataByFilter")]
MyResponse GetData(string filter);

Then another option is to use a DataContract instead of multiple parameters, and set IsRequired to false on the appropriate DataMember s, like explained in this question .

I get the compiler whining and weeping about no method with signature of a single parameter.

Start at the beginning. That your compiler "whines" is because the service does not recognize optional parameters with default values, so it will just expose the method requiring all parameters. Based on this metadata you generate a client proxy ("Service Reference"), which also doesn't contain the method you expect; it only sees the method the service exposes: the one with the (String beep, String boop) signature. So that's why, in the end, you receive a compile error when you try to call a non-existing method on a class.

Now when you call this method on the service, your client will have to provide both values. If you supply null , the service will see null , as the values for the default parameters have to be compiled into the caller. WCF does not support that, so you'll just have to create overloads as @StephenBorg suggested.

You can do it like this:

[DataContract]
public class GetStuffParams
{
    [DataMember]
    string beep {get; set; }

    [DataMember]
    string boop  {get; set;}


    public GetStuffParams() { boop = "too lazy to type"; }
}


[OperationContract]
[WebGet]
String GetStuff(GetStuffParams stuffParams);

you should check out the code generated when adding the service reference.

as the code is generated from WISDL, where the signature is (pseudo):

GetStuff(String , String )

it generates the code accordingly, not knowing about the optional parameters. so, if you want to get lazy, you should alter the proxy class generated or, as @Stephen Borg suggested, overload the function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM