2011-09-07 105 views
0

我有一個Web服務,它使用對System.ServiceModel.Dispatcher.SerializeReply消息的調用(具體爲MultiplexingDispatchMessageFormatter實現)。當我進行這個調用時,我得到一個「Key not found」異常,我追蹤到了System.ServiceModel.Dispatcher.MultiplexingDispatchMessageFormatter中的一行,它試圖根據一個鍵獲取「defaultContentType」。在Web服務中,當我嘗試序列化爲JSON消息時,出現「未找到密鑰」異常

不幸的是我無法看到關鍵是什麼,但defaultContentType集合似乎沒有任何項目。

我需要做些什麼來獲得SerializeReply的工作?

的代碼:

public System.ServiceModel.Channels.Message SerializeReply(System.ServiceModel.Channels.MessageVersion messageVersion, object[] parameters, object result) 
{ 
    System.Web.HttpRequest requestMessage = System.Web.HttpContext.Current.Request; 

    string format = requestMessage.QueryString["format"]; 
    if (!string.IsNullOrEmpty(format) && string.Compare(format, "json", true) == 0) 
    { 
    return jsonResponseDispatchMessageFormatter.SerializeReply(messageVersion, parameters, result); 
    } 
    //[UNRELATED CODE] 
} 

這是真實的System.ServiceModel.Dispatcher.MultiplexingDispatchMessageFormatter炸燬線(關鍵是 「JSON」 時,defaultContentTypes沒有入口):

outgoingResponse.ContentType = this.defaultContentTypes[key]; 

和異常我越來越:

System.Collections.Generic.KeyNotFoundException occurred 
Message=The given key was not present in the dictionary. 
Source=mscorlib 
StackTrace: 
    at System.ThrowHelper.ThrowKeyNotFoundException() 
InnerException: 
+0

你可以發佈你正在使用的代碼(你在哪裏調用SerializeReply)和問題的完整異常堆棧嗎? – carlosfigueira

+0

完成,不幸的是,這個例外並不能提供很多信息 – Dugan

回答

5

我有這個問題,FIGUR編輯如何解決它與我的情況與良好的醇'反射器。原因是OutgoingResponse的ContentType是空的。添加致電前「SerializeReply」對你jsonResponseDispatchMessageFormatter可能做的伎倆緊隨其後:

WebOperationContext.Current.OutgoingResponse.ContentType = "application/json"; 
0

接受的答案的作品。但是,如果您希望端點支持XML和JSON,則取決於配置了哪個屬性,下面的代碼對於任何一種方案都更加健壯。

/// <summary> 
    /// Try to set the content type as close to the user's preference as we can get. 
    /// </summary> 
    private void SetContentType() 
    { 
     if (WebOperationContext.Current == null) 
     { 
      throw new InvalidOperationException("There is no WebOperationContext. This class expects to operate within a WCF context."); 
     } 

     WebMessageFormat contentType = WebMessageFormat.Json; 

     //first let's grab the default, if possible 
     if (_serviceEndpoint.EndpointBehaviors.Contains(typeof (WebHttpBehavior))) 
     { 
      var behavior = (WebHttpBehavior)_serviceEndpoint.EndpointBehaviors[typeof (WebHttpBehavior)]; 
      contentType = behavior.DefaultOutgoingResponseFormat; 
     } 
     else if (_serviceEndpoint.EndpointBehaviors.Contains(typeof(WebHttpByteResponseBehavior))) 
     { 
      var behavior = (WebHttpByteResponseBehavior)_serviceEndpoint.EndpointBehaviors[typeof(WebHttpByteResponseBehavior)]; 
      contentType = behavior.DefaultOutgoingResponseFormat; 
     } 

     //then let's see if an explicit override is available 
     if (_operationDescription.OperationBehaviors.Contains(typeof (WebInvokeAttribute))) 
     { 
      var behavior = (WebInvokeAttribute)_operationDescription.OperationBehaviors[typeof(WebInvokeAttribute)]; 

      if (behavior.IsResponseFormatSetExplicitly) 
      { 
       contentType = behavior.ResponseFormat; 
      } 
     } 
     else if (_operationDescription.OperationBehaviors.Contains(typeof(WebGetAttribute))) 
     { 
      var behavior = (WebGetAttribute)_operationDescription.OperationBehaviors[typeof(WebGetAttribute)]; 

      if (behavior.IsResponseFormatSetExplicitly) 
      { 
       contentType = behavior.ResponseFormat; 
      } 
     } 

     //finally set the content type based on whatever we found 
     WebOperationContext.Current.OutgoingResponse.ContentType = MapToStringContentType(contentType); 
    } 

    /// <summary> 
    /// Maps from a WebMessageFormat to a valid Content-Type header value. 
    /// </summary> 
    /// <param name="contentType"></param> 
    /// <returns></returns> 
    private string MapToStringContentType(WebMessageFormat contentType) 
    { 
     switch (contentType) 
     { 
      case WebMessageFormat.Xml: 
       return TEXT_XML; 
       break; 
      case WebMessageFormat.Json: 
       return APPLICATION_JSON; 
       break; 
      default: 
       return APPLICATION_JSON; 
       break; 
     } 
    } 

然後,就請確保調用SetContentType()你打電話之前SerializeReply(...)。這主要適用於在有時調用自己的格式化程序的情況下調用某個內置WCF格式化程序,否則調用內置的WCF格式化程序。

相關問題