【问题标题】:WCF Rest Client sending incorrect content-typeWCF Rest 客户端发送不正确的内容类型
【发布时间】:2012-10-10 03:26:20
【问题描述】:

我正在尝试使用 wcf 客户端向使用 json 的 ColdFusion 9 服务发送请求。但是,请求的内容类型是xml。

这是服务合同。如您所见,我们具体使用 json 的 RequestFormat。

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

我也尝试在 OutGoing 请求上设置 Request.ContentType,但这也不起作用。

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

这是发送的请求

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

如何让它使用正确的内容类型?

编辑:

在后台,GetServiceClient(clientId) 调用使用 system.servicemodel.clientbase 和 ChannelFactory 来创建通信通道。我们调用的端点由客户端更改,因此我们在这些代码之上有一些代码可以动态更改端点。

更多信息。我们有两个应用程序:一个是用于托管客户端应用程序的 .net MVC 4 Web 应用程序,另一个是用于托管后端服务的 .net WCF 服务器应用程序。我可以从 Web 应用程序成功调用 ColdFusion 应用程序,但不能从 wcf 服务器应用程序调用。它们都使用相同的代码库来拨打电话。

据我所知,两者的配置相同。

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

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

【问题讨论】:

  • 您能否发布有关如何发送请求的代码?将服务中传出响应的 content-type 设置为 json,返回 json 格式的 CreateUserResponse 对象。
  • 第二个代码 sn -p 是发送请求的代码。这使用 System.ServiceModel 创建用于发送请求的 IClientChannel。构建和发送请求的所有工作都由 WCF 完成。
  • 您是否尝试执行 REST 请求。 GetServiceClient 是否存在于从 wsdl 生成的代理中。如果您正在使用它,那么我猜您正在尝试使用 SOAP 调用该服务。为了以 RESTful 方式调用 WCF 服务,您需要使用 HttpWebRequest 类
  • 请参阅以下代码示例以访问 RESTful Web 服务。
  • WCF 中显示以下跟踪:通过通道发送消息,默认内容类型映射器选择了请求格式,'xml',给定内容类型,'text/html'

标签: c# json wcf rest coldfusion


【解决方案1】:

要在服务中使用 WCF REST 客户端,您需要使用类似于下面的代码来创建新的操作上下文范围。

调用代码:

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

其他实现

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

【讨论】:

  • 这基本上就是我们目前正在做的事情。我们的 GetServiceClient 方法返回一个客户端。我们使用通道来调用服务方法。这不起作用。这是另一篇文章,其中用户尝试做同样的事情并在控制台应用程序中工作,但不在另一个服务调用中。 stackoverflow.com/questions/9567589/…
  • 您是否正在创建一个新的OperationContextScope,并在该范围内发出请求?
  • 你说得对,我错过了。 Operation Context 似乎解决了我的问题。谢谢。
【解决方案2】:

请找到一些关于如何使用 WebRequest 调用 WCF 服务的示例代码

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

【讨论】:

  • 因此您可以使用 WCF 框架来创建服务,并将所有这些东西抽象化。但是要调用宁静的服务,您必须自己完成所有工作吗?这似乎不对,也不是我所看到的。我可以调用一个安静的服务,在一种情况下,一切正常。另一方面,唯一的问题是内容类型设置不正确。
猜你喜欢
  • 2012-03-22
  • 2014-11-21
  • 1970-01-01
  • 2019-12-16
  • 1970-01-01
  • 1970-01-01
  • 2013-02-03
  • 2013-02-05
  • 1970-01-01
相关资源
最近更新 更多