2016-07-10 54 views
1

我在MVC項目中開發了Web API。我在我的post方法中返回一個JToken對象。通常我的API正常工作,但在特定的數據有時我得到這個錯誤:從asp.net POST方法返回JSON時出現「Unable to translate Unicode character \ uD83C」錯誤

"Message": "An error has occurred.", 
    "ExceptionMessage": "The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'.", 
    "ExceptionType": "System.InvalidOperationException", 
    "StackTrace": null, 
    "InnerException": { 
    "Message": "An error has occurred.", 
    "ExceptionMessage": "Unable to translate Unicode character \\uD83C 
    at index 411 to specified code page." 

這是我的POST方法

public JToken Post([FromBody]Classes.Search search) 
    { 

     Classes.ReturnSearch returnSearch = new Classes.ReturnSearch(); 
     try 
     { 
      string con = System.Configuration.ConfigurationManager.ConnectionStrings["TConnectionString"].ConnectionString; 
      SqlConnection cn = new SqlConnection(con); 
      SqlDataAdapter sqlDataAdapter = new SqlDataAdapter("SP_Searchi", cn); 
      sqlDataAdapter.SelectCommand.CommandType = CommandType.StoredProcedure; 
      sqlDataAdapter.SelectCommand.Parameters.Add(new SqlParameter("@word", search.word)); 

      sqlDataAdapter.SelectCommand.Parameters.Add(new SqlParameter("@num", search.num)); 
      DataSet d = new DataSet(); 
      sqlDataAdapter.Fill(d); 
      DataTable table = d.Tables[0]; 

      foreach(DataRow row in table.Rows) 
      { 
       string result=row[1].ToString(); 

       returnSearch.search_items.Add(new Classes.SearchItem(row[0].ToString(), row[1].ToString(),search.word)); 
      } 
      returnSearch.status = "Success"; 


      return JObject.Parse(JsonConvert.SerializeObject(returnSearch)); 
     } 
     catch (Exception e) 
     { 
      returnSearch.status = "Failed"; 
      returnSearch.search_items = null; 
      ValuesController.Log("Error in Search: "+e.Message); 
      return JObject.Parse(JsonConvert.SerializeObject(returnSearch)); 
     } 


    } 

有什麼問題?

+0

['U + D83C'不是有效的Unicode字符](http://www.fileformat.info/info/unicode/char/d83c/index.htm)。這個角色是如何出現在你的返回對象中的? – dbc

+0

我繼續並修改了原始標題*旋轉後的重疊循環視圖*可以更好地反映問題。如果這是不可取的,請隨時更換。 – dbc

回答

1

你的問題是U+D83C is not a valid unicode character仍然以某種方式進入到你的returnSearch對象中的一個字符串中。隨後,asp.net-mvc框架拋出一個異常,試圖將這樣一個字符編碼爲utf-8。

你需要做的是確定這個角色如何進入你的returnSearch結果並修復這個潛在的問題。由於您已經手動將返回的結果轉換爲JObject,爲了使調試更加容易,您可以使用以下轉換器將所有字符串測試編碼爲utf-8並引發異常:

public class EncodingValidatingStringConverter : JsonConverter 
{ 
    readonly Encoding encoding; 

    public EncodingValidatingStringConverter() 
     : this(Encoding.GetEncoding(Encoding.UTF8.CodePage, new EncoderReplacementFallback("?"), new DecoderExceptionFallback())) 
    { 
    } 

    public EncodingValidatingStringConverter(Encoding encoding) 
    { 
     if (encoding == null) 
      throw new ArgumentNullException(); 
     this.encoding = encoding; 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     return objectType == typeof(string); 
    } 

    public override bool CanRead { get { return false; } } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     var s = (string)value; 
     var bytes = encoding.GetBytes(s); 
     var sFixed = encoding.GetString(bytes); 

     writer.WriteValue(sFixed); 
    } 
} 

然後修改您的Post()方法來捕獲並記錄EncoderFallbackException並處理該問題,這似乎是明智的。例如,你的方法及其以下版本登錄後替換爲?字符無效字符:

 try 
     { 
      // Fill in the returnSearch 

      // Convert to JObject and return 
      var settings = new JsonSerializerSettings 
      { 
       Converters = new[] { new EncodingValidatingStringConverter(Encoding.GetEncoding(Encoding.UTF8.CodePage, new EncoderExceptionFallback(), new DecoderExceptionFallback())) }, 
      }; 
      return JObject.FromObject(returnSearch, JsonSerializer.CreateDefault(settings)); 
     } 
     catch (EncoderFallbackException ex) 
     { 
      // Log the encoding error for debugging: 
      ValuesController.Log("Encoding exception:\n" + ex.ToString()); 
      // You could log the search parameters or entire search_items list as well if desired. 

      // Return whatever seems most advisable, e.g. replacing the bad character with a fallback if preferred. 
      var settings = new JsonSerializerSettings 
      { 
       Converters = new[] { new EncodingValidatingStringConverter(Encoding.GetEncoding(Encoding.UTF8.CodePage, new EncoderReplacementFallback("?"), new DecoderExceptionFallback())) }, 
      }; 
      return JObject.FromObject(returnSearch, JsonSerializer.CreateDefault(settings)); 
     } 
     catch (Exception ex) 
     { 
      returnSearch.status = "Failed"; 
      returnSearch.search_items = null; 
      ValuesController.Log("Error in Search: " + ex.Message); 
      var settings = new JsonSerializerSettings 
      { 
       Converters = new[] { new EncodingValidatingStringConverter(Encoding.GetEncoding(Encoding.UTF8.CodePage, new EncoderReplacementFallback("?"), new DecoderExceptionFallback())) }, 
      }; 
      return JObject.FromObject(returnSearch, JsonSerializer.CreateDefault(settings)); 
     } 

說明:測試編碼每個字符串都會有負面的性能影響,所以一旦你有固定的,你應該刪除潛在的問題此解決方法。

順便提一下,不是JObject.Parse(JsonConvert.SerializeObject(returnSearch))你可以做JObject.FromObject(returnSearch)。此方法直接寫入JToken層次結構,沒有中間字符串表示,因此應具有更好的性能。

2

這是一個表情符號修飾符。解析輸入的表情符號(可以拆分爲許多\ u ####實例)後,您可能會看到它。

相關問題