WCF Post with Query String

2019-04-12 00:48发布

问题:

I am currently developing a Windows Service hosted WCF service. One of the methods has a URI which is set up to receive a callback from a payment provider. This is the interface contract...

    [OperationContract]
    [WebInvoke(UriTemplate = "3DSecureCallback?TrxId={id}", Method = "POST", BodyStyle = WebMessageBodyStyle.Bare)]
    void ThreeDSecureCallBack(string id, Stream body);

This issue I am having is that the 3rd party provider posts to our service. I have to provide a callback url to it. So we can reconcile payments, we provide a URL with a query string parameter containing the transaction id.

During development of this service, the call backs have been successful. (This was prior to adding the Steam parameter)

However, we are now at the stage where we need to parse the posted data. This is the point that the 2nd 'Stream' parameter was added to the method signature.

The issue that I am getting is that I receive the following exception...

For request in operation ThreeDSecureCallBack to be a stream the operation must have a single parameter whose type is Stream.

By removing the id parameter, and having stream only, we can get the post data. This won't work in practice though as I need to query string paramter also.

Can anyone advise on how to resolve this issue please? I am really at a loss.

Thanks in advance,

David

回答1:

You can access the querystring "id" value as shown below

WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters["id"]

Now you can have only one parameter to your method of type stream.



回答2:

Waking up an old thread, but thought it'd be helpful to document another way of doing it.

Changing BodyStyle of the WeInvoke method to Wrapped will solve your problem where any parameters which you don't specify on the UriTemplate are assumed to come from the request body.

The only drawback is that you'll have to wrap your post data too... and either use built-in data types as extra parameters, or define your own suitable DataContract.

Example:

[DataContract]
public class PostInfo
{
  [DataMember]
  public string Info1;
  [DataMember]
  public string Info2;
}

[OperationContract]
[WebInvoke(UriTemplate = "3DSecureCallback?TrxId={id}", Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped)]
void ThreeDSecureCallBack(string id, PostInfo body);

Source: msdn Forums