将EF模型序列化为Json时的循环引用

时间:2016-05-17 15:52:27

标签: c# asp.net-mvc entity-framework serialization json.net

我知道有很多与此主题相关的问题,但是没有一个问题解决了我的问题。

我正在使用MVC 5和Entity Framework 6以及Newtonsoft.Json。

我有这种例外的常见情况:

Service => Staff => Service

当我尝试在我的视图中序列化service对象时,如下所示:

var arr = @Html.Raw(@JsonConvert.SerializeObject(Model.Services));

我得到了" circular reference was detected while serializing an object of type..."异常。

我在这里找到的所有答案都说它很难解决,我应该添加

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings
            .PreserveReferencesHandling = PreserveReferencesHandling.All;

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings
        .ReferenceLoopHandling = ReferenceLoopHandling.Serialize;

在我的Global.asax文件中。

嗯,我做了,它只是不起作用。我在MSDN上阅读了一堆文章,他们都说了同样的话。我不知道为什么,但它对我不起作用。

我能使其工作的唯一方法是在我的控制器中创建整个序列化上下文:

var settings = new JsonSerializerSettings
{
    PreserveReferencesHandling = PreserveReferencesHandling.All,
    ReferenceLoopHandling = ReferenceLoopHandling.Serialize
};


var serializer = JsonSerializer.Create(settings);
var msmStream = new MemoryStream();
var txtWriter = new StreamWriter(msmStream);
var writer = new JsonTextWriter(txtWriter) { Formatting = Formatting.Indented };
serializer.Serialize(writer, services);

var json = Encoding.ASCII.GetString(msmStream.GetBuffer());

然而,这是一个可怕的糟糕解决方案,特别是如果我在视图中动态地从我的视图模型中序列化属性。它也违背了全球配置的全部目的,并且#34;。

有人遇到过这个问题吗?

3 个答案:

答案 0 :(得分:1)

您需要将DefaultSettings更改为新的。

JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
    PreserveReferencesHandling = PreserveReferencesHandling.All,
    ReferenceLoopHandling = ReferenceLoopHandling.Serialize
};

来源

答案 1 :(得分:1)

默认的序列化设置需要按如下方式更改。 在Global.aspx中,

PHP CODE: 
<?php
    $server="localhost";
    $user="root";
    $password="11587496";
    $database="business";
    $databaseConnect=mysql_connect($server, $user, $password);
    $databaseFound=mysql_select_db($database, $databaseConnect);
    error_reporting(E_ALL);

    if(isset($_POST['productName'])){ $productName = $_POST['productName']; } 
    if(isset($_POST['quantity'])){ $quantity = $_POST['quantity']; } 
    if(isset($_POST['price'])){ $price = $_POST['price']; } 
    if(isset($_POST['sellingPrice'])){ $sellingPrice = $_POST['sellingPrice']; } 

    if($_POST['myaction']=="Add"){
    if($databaseFound){
        $SQL="INSERT INTO products(productName, quantity, price, sellingPrice) VALUES('".$productName."', '".$quantity."', '".$price."', '".$sellingPrice."')";
        $result=mysql_query($SQL);
    }
    else {
        print "Database NOT Found ";
        mysql_close($databaseConnect);
        return;
    }
    }
    else if($_POST["myaction"]=="Update"){
        //code for update query goes here
    }
    else if($_POST["myaction"]=="Delete") {
        //code for delete query goes here
    }
    ini_set('display_errors', 1);
?>
<form id="myform" action="add.php" method="POST" enctype="multipart/form-data">
                        <img src="pictures/defaultimage.png" class="submit mysubmit" id="mypic">
                        <input type="file" accept="image/*" name="file" id="pictureupload" onchange="loadFile(event)" class="submit mysubmit">
                        <input id="productName" name="productName" type="text" placeholder="Product Name" required class="submit mysubmit">
                        <input id="quantity" name="quantity" type="number" placeholder="Quantity" required class="submit mysubmit">
                        <input id="price" name="price" type="number" placeholder="Price" required class="submit mysubmit">
                        <input id="sellingPrice" name="sellingPrice" type="number" placeholder="Selling Price" required class="submit mysubmit">

                        <input type="submit" name="myaction" value="Add" class="submit" id="add">
                        <input type="submit" name="myaction" value="Update" class="submit" id="update">
                        <input type="submit" name="myaction" value="Delete" class="submit" id="delete">
                    </form>`enter code here`

答案 2 :(得分:0)

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings仅影响Web API调用。由于您直接呼叫JsonConvert.SerializeObject,您需要将设置直接传递给它,如下所示,或者设置全局默认设置,如@ vendettamit的答案所示。

var arr = @Html.Raw(@JsonConvert.SerializeObject(Model.Services, new JsonSerializerSettings
                    { PreserveReferencesHandling = PreserveReferencesHandling.All }));