WCF Rest Client sending incorrect content-type

2019-05-11 06:10发布

I am trying to send a request using a wcf client to a ColdFusion 9 service using json. However, the content-type of the request is for xml.

Here is the service contract. As you can see we specificy using RequestFormat of json.

[ServiceContract(Name = "ServiceAgreementRequestService", Namespace = NetworkNamespaces.ServiceNamespace)]
public interface IServiceAgreementRequestService
{
[OperationContract]
[FaultContract(typeof(RequestFault))]
[WebInvoke(UriTemplate = "?method=CreateUser", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
CreateUserResponse CreateUser(CreateUserRequest request);
}

I have also tried to set the Request.ContentType on the OutGoing request and this also did not work.

using (var context = this.GetServiceClient(clientId))
{
WebOperationContext.Current.OutgoingRequest.ContentType = "application/json; charset=UTF-8";
var request = new CreateUserRequest(user.Id, user.Person.FirstName, user.Person.LastName);
var response = context.Channel.CreateUser(request);
}

Here is the request that gets sent

POST http://somesite.domain.com/WebServices/ProviderService.cfc/?method=CreateUser HTTP/1.1
Content-Type: application/xml; charset=utf-8
VsDebuggerCausalityData: uIDPo7eh9U9jsBVLqVgGtqTK+eMBAAAAb++0xkOSQEmcAKZLgQEsp2/muY2ca6NJiul6pkAaWZwACQAA
Host: somehost.domain.com
Content-Length: 58
Expect: 100-continue
Accept-Encoding: gzip, deflate

{"UserId":4,"FirstName":"FirstName","LastName":"LastName"}

How do I get this to use the correct content-type?

EDIT:

Under the hood, the GetServiceClient(clientId) call uses system.servicemodel.clientbase and ChannelFactory to create the communication channel. The endpoint that we call out to changes by client so we have some code on top of those to dynamically change out the endpoint.

Some more info. We have two applications : One is a .net MVC 4 web application to host the client app and one is a .net WCF Server application to host the backend services. I can call out to the ColdFusion app successfully from the web application, but not the wcf Server application. These both use the same code base to make the outgoing call.

As far as I can tell the config is the same for both.

<system.serviceModel>
<endpointBehaviors>
<behavior name="WcfRestBehavior">
<webHttp />
</behavior>

<client>
<endpoint name="ServiceAgreementRequestService" address="http://PLACEHOLDER/" binding="webHttpBinding" behaviorConfiguration="WcfRestBehavior" contract="IServiceAgreementRequestService"/>

2条回答
Rolldiameter
2楼-- · 2019-05-11 06:16

To use the WCF REST Client within a service, you'll need to create a new operation context scope, by using code similar to the one below.

Calling code:

var client = this.GetServiceClient(clientId);
using (new OperationContextScope(client.InnerChannel))
{ 
    var request = new CreateUserRequest(user.Id, user.Person.FirstName, user.Person.LastName); 
    var response = client.CreateUser(request); 
} 

Other implementations:

class MyType : ClientBase<IServiceClient>, IServiceClient
{
    public MyType() : base("ServiceAgreementRequestService") { }
    public CreateUserResponse CreateUser(CreateUserRequest req)
    {
        return this.Channel.CreateUser(req);
    }
}

public MyType GetServiceClient(int clientId)
{
    return new MyType();
}
查看更多
家丑人穷心不美
3楼-- · 2019-05-11 06:26

Please find some sample code on how to invoke the WCF service using WebRequest

var request = WebRequest.Create(string.Concat(serviceUrl, resourceUrl)) as HttpWebRequest;
            if (request != null)
            {
                request.ContentType = "application/json";
                request.Method = method;
            }

            if(method == "POST" && requestBody != null)
            {
                requestBodyBytes = ToByteArrayUsingDataContractSer(requestBody);
                request.ContentLength = requestBodyBytes.Length;
                using (Stream postStream = request.GetRequestStream())
                    postStream.Write(requestBodyBytes, 0, requestBodyBytes.Length);                    
            }

            if (request != null)
            {
                var response = request.GetResponse() as HttpWebResponse;
                if(response.StatusCode == HttpStatusCode.OK)
                {
                    Stream responseStream = response.GetResponseStream();
                    if (responseStream != null)
                    {
                        var reader = new StreamReader(responseStream);
                        responseMessage = reader.ReadToEnd();                        
                    }
                }
                else
                {   
                    responseMessage = response.StatusDescription;
                }
            }

    private static byte[] ToByteArrayUsingDataContractSer<T>(T requestBody)
    {
        byte[] bytes = null;
        var serializer1 = new DataContractSerializer(typeof(T));            
        var ms1 = new MemoryStream();            
        serializer1.WriteObject(ms1, requestBody);
        ms1.Position = 0;
        var reader = new StreamReader(ms1);
        bytes = ms1.ToArray();
        return bytes;            
    }
查看更多
登录 后发表回答