Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何自定义JSON对象序列化?_C#_Ajax_Asp.net Mvc_Entity Framework_Json.net - Fatal编程技术网

C# 如何自定义JSON对象序列化?

C# 如何自定义JSON对象序列化?,c#,ajax,asp.net-mvc,entity-framework,json.net,C#,Ajax,Asp.net Mvc,Entity Framework,Json.net,我有一个ASP.NETRazor页面,其中我试图使用jQueryAjax请求显示日志列表。根据我在文档和论坛中的理解,我提出了以下ajax请求: $.ajax({ url: '@Url.Action("GetLogs","Logs")', dataType: "json", contentType :"application/json; charset=utf-8", success: function (data) { console.log("

我有一个ASP.NETRazor页面,其中我试图使用jQueryAjax请求显示日志列表。根据我在文档和论坛中的理解,我提出了以下ajax请求:

$.ajax({
    url: '@Url.Action("GetLogs","Logs")',
    dataType: "json",
    contentType :"application/json; charset=utf-8",
    success: function (data) {
        console.log("success");
        console.log(data);
    },
    error: function (msg) {
        console.log("error");
        console.log(msg);
    }
});
这是可行的,但是它返回的json并不是我想要的。以下是ajax请求和getAllLogs函数调用的控制器代码:

- LogsController -
public JsonResult GetLogs()
{
    List<Log> _loglist = LogsModel.getAllLogs(UserModel.getUser(Session["FirstName"].ToString(), Session["LastName"].ToString()));

    String json = JsonConvert.SerializeObject(_loglist, Formatting.Indented, new JsonSerializerSettings
    {
        ReferenceLoopHandling = ReferenceLoopHandling.Ignore

    });

    return Json(json, JsonRequestBehavior.AllowGet);
}

- LogsModel -
//get all logs to display in admin tab
public static List<Log> getAllLogs(User _user)
{
    // if user is admin we can show logs concerning all users
    if(UserModel.isAdmin(_user))
        return db.Logs.Where(log => log.Action.Equals("Set Characteristic")).OrderByDescending(log => log.Id).ToList();
    else
        //user is manager and will see only users in same plant
        return db.Logs.Where(log => log.User.Plant.Code.Equals(_user.Plant.Code) && log.Action.Equals("Set Characteristic")).OrderByDescending(log => log.Id).ToList();
        }
首先,我设计了数据库,用户对象与日志一起返回,因此返回的是Json:

[
  {
    "User": {
      "Characteristic_Value": [],
      "Logs": [
        {
          "Id": 1,
          "User_Id": 1,
          "Date": "2014-08-11T14:11:52.523",
          "Action": "Login attempt",
          "State": true,
          "Message": "User successfully logged in"
        },
        {
          "Id": 2,
          "User_Id": 1,
          "Date": "2014-08-11T14:13:45.07",
          "Action": "Login attempt",
          "State": true,
          "Message": "User successfully logged in"
        },
        {
          "Id": 3,
          "User_Id": 1,
          "Date": "2014-08-11T14:15:07.043",
          "Action": "Login attempt",
          "State": true,
          "Message": "User successfully logged in"
        },
    Other User Data ...
    },
    "Id" : 21,
    "User_Id": 1,
    "Date": "2014-08-11T10:00:00.000",
    "Action": "Set Characteristic",
    "State": true,
    "Message" : "User changed characteristic [charac_name]"
  }
]
我得到了所有的用户数据。我是唯一一个在这个项目上工作的人,所以现在获取数据不需要很长时间,但在不久的将来,将有更多的用户,需要查询的数据量将永远不会停止增加,我非常担心响应时间

所以最后我的问题是:是否有可能删除随日志返回的用户数据


我仍然对JsonSerializerSettings感到困惑,但也许这就是解决这个问题的方法?

我认为您有两种选择:

将不希望序列化的属性标记为[JsonIgnore]。如果您的日志类位于一个真正不应该关心JSON序列化的不同层,那么这可能不是一个很好的选择

创建以表示确实要发送的信息,可以选择使用AutoMapper之类的工具将类映射到一起

例如,LogViewModel可能如下所示:

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

    public int User_Id { get; set; }

    public DateTime Date { get; set; }

    public string Action { get; set; }

    public bool State { get; set; }

    public string Message { get; set; }
}
然后,您应该调整代码以序列化一组LogViewModels:

IEnumerable<LogViewModel> viewModels =
    _logList.Select(l => new LogViewModel
    {
        Id = l.Id,
        User_Id = l.User_Id
        /* etc. */
    });        

String json = JsonConvert.SerializeObject(viewModels);
上面的映射代码可能会变得单调乏味,这就是像这样的工具的用武之地

您也可以只投影一个匿名类型,其中包含您关心的属性,效果类似,但是我发现管理ViewModels要容易得多


我建议您选择ViewModel路线,尤其是当人们在系统的这个特定区域添加您不关心的属性时,它可以很好地分离关注点并保护您免受问题的困扰。

为什么不在linq中选择日志?我不确定您的意思。但我想这就是我在getAllLogs函数中所做的。对于实体框架,因为我在指向用户表的日志中有一个foreignkey,对于我得到的每个日志,我都会得到所有的用户信息。我不确定我能不能解释清楚。我没有日志类,每个类都是base中的表,所以我不能使用注释。2.我要试试这个:它来自于漫游论坛之类的东西,但我并不真正理解它,我认为ViewModels与MVCViewModels不兼容。它们只是一种模式,在ASP.NET MVC中被广泛使用。它们与MVVM中ViewModel的含义不同,虽然我刚刚安装了automapper并创建了LogsViewModel,而且效果非常好:非常感谢@尼迪文:没问题!很乐意帮忙。
IEnumerable<LogViewModel> viewModels =
    _logList.Select(l => new LogViewModel
    {
        Id = l.Id,
        User_Id = l.User_Id
        /* etc. */
    });        

String json = JsonConvert.SerializeObject(viewModels);