2013-09-22 106 views
0

返回城堡DynamicProxy對象時,我有一些問題調用signalr集線器時,返回的對象是一個Castle DynamicProxySignalR樞紐調用不起作用沒有默認構造

比方說,我對signalr樞紐以下服務器的代碼(這不是真正的代碼,但只是爲了說明問題):

public Article Read() 
{ 
    var article = new Article(0); 
    return article; 
} 
public class Article 
{ 
    public Article(int id) 
    { 
     Id = id; 
    } 

    public int Id { get; set; } 
} 

上述方法正確返回我的對象​​。如果我這個代碼更改爲:

public Article Read() 
{ 
    var proxyGenerator = new Castle.DynamicProxy.ProxyGenerator(); 
    var entity = proxyGenerator.CreateClassProxy(typeof(Article), new object[]{0}, new TestInterceptor()) as Article; ; 
    return entity; 
} 
class TestInterceptor : Castle.DynamicProxy.IInterceptor 
{ 
    public void Intercept(Castle.DynamicProxy.IInvocation invocation) 
    { 
    } 
} 

從未返回的對象。客戶端(javascript)不會收到任何錯誤,並且都不會執行donefail函數。

我懷疑它是與序列化的問題。如果我嘗試使用Newtonsoft序列化對象,我會得到以下錯誤:

System.ArgumentNullException was unhandled by user code 
    HResult=-2147467261 
    Message=Value cannot be null. 
Parameter name: key 
    Source=mscorlib 
    ParamName=key 
    StackTrace: 
     at System.Collections.ObjectModel.KeyedCollection`2.Contains(TKey key) 
     at Newtonsoft.Json.Serialization.JsonPropertyCollection.AddProperty(JsonProperty property) 
     at Newtonsoft.Json.Serialization.DefaultContractResolver.CreateConstructorParameters(ConstructorInfo constructor, JsonPropertyCollection memberProperties) 
     at Newtonsoft.Json.Serialization.DefaultContractResolver.CreateObjectContract(Type objectType) 
     at Newtonsoft.Json.Serialization.DefaultContractResolver.CreateContract(Type objectType) 
     at Newtonsoft.Json.Serialization.DefaultContractResolver.ResolveContract(Type type) 
     at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.GetContractSafe(Object value) 
     at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType) 
     at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType) 
     at Newtonsoft.Json.JsonSerializer.Serialize(JsonWriter jsonWriter, Object value, Type objectType) 
     at Newtonsoft.Json.JsonConvert.SerializeObject(Object value, Type type, Formatting formatting, JsonSerializerSettings settings) 
     at Newtonsoft.Json.JsonConvert.SerializeObject(Object value, Formatting formatting, JsonSerializerSettings settings) 
     at Newtonsoft.Json.JsonConvert.SerializeObject(Object value) 
    InnerException: 

任何想法?這是signalr的序列化問題?

編輯:

感謝安德斯我發現,只有當類已創建動態代理沒有默認構造函數時出現問題。例如public Article(int id)。這是Json.NET序列化的問題?

+0

SignalR使用JSON.NET所以如果JSON.NET無法反序列化對象出於某種原因(以上除外),它不會在SignalR工作,要麼。 – davidfowl

+0

@dfowler謝謝大衛。唯一奇怪的想法是我從SignalR沒有收到任何錯誤。最終可以使用自定義序列化?或者直接返回一個json? –

+0

我們不會在這裏給出很好的錯誤,因爲我們以塊的形式編寫響應。我們將考慮報告這個錯誤是未來更好的方法。 你當然可以序列化你自己併發送字符串(儘管你會雙重序列化)。 JSON.NET也具有串行器可插入性 – davidfowl

回答

1

經過一番調查後,我發現了這個問題。這是Json.NET上的一個小錯誤。我已經在json.net網站上創建了一個new issue,現在已經解決了。

1

Json.Net沒有問題序列化一個動態代理,這個工作對我來說

class Program 
{ 
    static void Main(string[] args) 
    { 
     var proxyGenerator = new Castle.DynamicProxy.ProxyGenerator(); 
     var entity = proxyGenerator.CreateClassProxy(typeof(Article), new object[0], new TestInterceptor()) as Article; ; 
     var json = JsonConvert.SerializeObject(entity); 
    } 
} 

public class Article 
{ 
    public int Id { get; set; } 
} 

class TestInterceptor : Castle.DynamicProxy.IInterceptor 
{ 
    public void Intercept(Castle.DynamicProxy.IInvocation invocation) 
    { 
    } 
} 

結果是

{"__interceptors":[{}],"Id":0} 

更新:

無參數的構造函數,我得到一個厚望的媒體鏈接城堡

Can not instantiate proxy of class: ConsoleApplication1.Article. 

Could not find a parameterless constructor. 
+0

對不起,安德斯你是對的。事實上,我的產品代碼略有不同。當類沒有默認構造函數時,使用動態代理似乎是一個問題。基本上,如果Article類只有一個帶參數的構造函數,比如'public Article(int id)',那麼異常ArgumentNullException就是throw。你認爲這是Json.NET的錯誤嗎?考慮一下,如果我在沒有DynamicProxy的情況下序列化同一個類,它就可以正常工作。 –

+0

請參閱我的更新 – Anders

+0

您必須將構造函數參數傳遞給代理生成器:'proxyGenerator。CreateClassProxy(typeof(Article),new object [] {param1},new TestInterceptor())as Article;'這樣Castle正確生成代理,但Json.NET在序列化時拋出異常。 –