Access Visual Studio 2017's Private Registry Hive

Can I have an optional parameter for an ASP.NET SOAP web service

You can have a Overloaded Method in webservices with MessageName attribute. This is a workaround to achieve the overloading functionality.

Look at http://msdn.microsoft.com/en-us/library/byxd99hx%28VS.71%29.aspx

[WebMethod(MessageName="Add3")]
public double Add(double dValueOne, double dValueTwo, double dValueThree)
{
return dValueOne + dValueTwo + dValueThree;
}

[WebMethod(MessageName="Add2")]
public int Add(double dValueOne, double dValueTwo)
{
return dValueOne + dValueTwo;
}

The methods will be made visible as Add2 and Add3to the outside.

Optional parameters in ASP.NET web service

I am assuming that when you say ASP.net web services, you are creating web services with ASMX extension. I think that what happens in this case is that all nullable types become optional and non-nullable become non-optional.

You could perhaps manually edit the generated WSDL file. But then you would have to redo that work if the wsdl was regenerated.

I would suggest that you switch to WCF with basisHttpBinding (except for the name of you service your clients should not notice the difference).

Using WCF you can simply mark the parameter in the data contract as required or not:

[DataMember(IsRequired="false")]

How to build web service/web api with optional parameters in C#

basically you cant do that.

i suggest you to read this article first:
http://blogs.msdn.com/b/jmstall/archive/2012/04/16/how-webapi-does-parameter-binding.aspx

it explains pretty well how parameters are bound.

how to send optional parameters to a webservice in c#?

You cannot send optional parameters to a SOAP web service. The SOAP protocol has no concept of optional parameters.

Also, you should not be using ASMX services at all. That's a legacy technology that shouldn't be used for new development. WCF should be used instead.

How to pass optional parameters for web method?

You can't. Web methods doesn't support optional parameters. When you generate proxy for web method, you make get the specific signature, according to which you client and server would exchange the messages. But it can't pass the optional parameters. You can use default parameters on the server side, but no optional.

How to add more parameters to a JSON WebService without breaking call from old clients?

It looks like the proper way to achieve that is to use method overloads for your service methods. Also for the future methods I would recommend you using models:

public class MyModel
{
public string Message { get; set; }
public string AdditionalInfo { get; set; }
}

and then:

[WebMethod]
public string Ping(MyModel model)
{
...
}

This will give you more flexibility because you will be able to add properties easily in the future without breaking.

This being said, there's one approach or a workaround that you might consider: manual deserialization (I totally don't recommend it but worth mentioning).

Make your WebMethod without any parameters:

[WebMethod]
public string Ping()

and then read the request body manually by accessing the input stream:

[WebMethod]
public string Ping()
{
Context.Request.InputStream.Seek(0, SeekOrigin.Begin);
using (var inputStream = Context.Request.InputStream)
using (var reader = new StreamReader(inputStream))
{
string body = reader.ReadToEnd();

// TODO: Worth checking the request headers before attempting JSON deserialization
// For example the Content-Type header
var model = JsonConvert.DeserializeObject<MyModel>(body);
if (string.IsNullOrEmpty(model.AdditionalInfo))
{
return "Process msg with old version";
}
return "Process msg with new version"; ;
}
}

To avoid mixing multiple responsibilities in your service method you could move the parsing of the body stream into some separate extension method:

public static class RequestExtensions
{
public static T ParseRequest<T>(this HttpRequest request)
{
request.InputStream.Seek(0, SeekOrigin.Begin);
using (var inputStream = request.InputStream)
using (var reader = new StreamReader(inputStream))
{
string body = reader.ReadToEnd();
return JsonConvert.DeserializeObject<T>(body);
}
}
}

and then your WebMethod:

[WebMethod]
public string Ping()
{
var model = Context.Request.ParseRequest<MyModel>();
if (string.IsNullOrEmpty(model.AdditionalInfo))
{
return "Process msg with old version";
}
return "Process msg with new version"; ;
}

Now clients can call the Ping method like that:

POST /WebService1.asmx/Ping HTTP/1.1
Content-type: application/json; charset=utf-8
Host: localhost:14529
Content-Length: 61

{
"msg": "Hello",
"additionalInfo": "add info"
}

or the old way:

POST /WebService1.asmx/Ping HTTP/1.1
Content-type: application/json; charset=utf-8
Host: localhost:14529
Content-Length: 26

{
"msg": "Hello"
}


Related Topics



Leave a reply



Submit