Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.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# 序列化api数据时出错:无法序列化为JSON,因为其IsReference设置为';正确';_C#_Json_Api_Serialization - Fatal编程技术网

C# 序列化api数据时出错:无法序列化为JSON,因为其IsReference设置为';正确';

C# 序列化api数据时出错:无法序列化为JSON,因为其IsReference设置为';正确';,c#,json,api,serialization,C#,Json,Api,Serialization,我已经创建了一个webApi。当我运行这个webapi时,我在浏览器中得到了预期的数据 公共IEnumerable GetAllProducts() 现在我想在我的项目中使用这个api服务 公共视图结果索引() } 但在反序列化时,我在返回serializer.ReadObject(stream)时出错;作为: 无法将类型“Product”序列化为JSON,因为其IsReference设置为“True”。JSON格式不支持引用,因为没有用于表示引用的标准格式。要启用序列化,请禁用该类型或该类型的

我已经创建了一个webApi。当我运行这个webapi时,我在浏览器中得到了预期的数据

公共IEnumerable GetAllProducts()

现在我想在我的项目中使用这个api服务

公共视图结果索引()

}

但在反序列化时,我在返回serializer.ReadObject(stream)时出错;作为:

无法将类型“Product”序列化为JSON,因为其IsReference设置为“True”。JSON格式不支持引用,因为没有用于表示引用的标准格式。要启用序列化,请禁用该类型或该类型的适当父类上的IsReference设置


有一些可能的想法可以尝试解决这个问题,主要原因是EntityFramework(或ur ORM)与序列化冲突

顺便说一句,如果您提供代码,请尝试提供可编译且有意义的代码。我无法重现您的问题,因为缺少代码。如果您可以包含所有代码(甚至是一个VisualStudio项目),我将尝试修复您的问题,而不是演示基于完全不同上下文的解决方案

  • 在我看来,您不应该从API返回ORM对象。而是返回DataTransferObjects。从序列化对象中删除实体框架,这样错误就会消失

  • 使用RestSharp进行restapi调用

  • 您可以使用以下属性标记产品实体

    [DataContract(IsReference=false)]

  • 尝试使用JSON.NET? 我将使用JSON.NET和DTO来实现这一点

  • 但我不明白的是你想要实现什么。为什么不简单地对API进行客户端调用呢?在这种情况下,我看不到服务器端API调用的好处。除非您的WebApi托管在不同的环境中,否则从服务器端调用它在任何情况下都没有意义。MVC项目似乎也引用了ORM对象层,这也有点奇怪(或者产品类不是映射到ur数据库的对象?)

    如果它们在同一台服务器上,以这种方式使用WebApi没有任何好处,而是创建一个提供所需信息的层,并将其包含在Api和控制器中,这样控制器就不需要使用Api,它可以直接调用另一层。它还删除了服务器端JSON反序列化

    我还注意到你的API返回“城市”,你正在将它们转换为产品,这听起来不奇怪吗

    编辑:工作示例:

    我已经创建了一个小应用程序,它正在为我工作。该示例可从以下网址下载:

    我使用restSharp从.NET中为DTO和EF相关对象创建Api调用

    非DTO示例:

    ApiController如下所示:

    public interface IApiExampleController
    {
        IEnumerable<User> GetAllUsers();
    }
    
    public class ApiExampleController : ApiController, IApiExampleController
    {
        private readonly IEFContext _context;
    
        public ApiExampleController()
        {
            _context = new EFContext();
        }
    
        public IEnumerable<User> GetAllUsers()
        {
            return _context.Users.ToList();
        }
    }
    
    public ActionResult Index()
    {
        var users = GetApiUsers();
        return View(users);
    }
    
    private IList<User> GetApiUsers()
    {
        const string apiBaseUrl = "http://localhost:52812/Api/";
        const string apiSuffix = "ApiExample/GetAllUsers";
    
        var client = new RestClient(apiBaseUrl);
    
        var request = new RestRequest(apiSuffix, Method.GET);
    
        var response = (RestResponse<List<User>>)client.Execute<List<User>>(request);
        return response.Data;
    }
    
    公共接口IApiExampleController
    {
    IEnumerable GetAllUsers();
    }
    公共类ApiExampleController:ApiController、IApiExampleController
    {
    私有只读IEFContext\u上下文;
    公共ApiExampleController()
    {
    _context=新的EFContext();
    }
    公共IEnumerable GetAllUsers()
    {
    return_context.Users.ToList();
    }
    }
    
    调用API的MVC控制器如下所示:

    public interface IApiExampleController
    {
        IEnumerable<User> GetAllUsers();
    }
    
    public class ApiExampleController : ApiController, IApiExampleController
    {
        private readonly IEFContext _context;
    
        public ApiExampleController()
        {
            _context = new EFContext();
        }
    
        public IEnumerable<User> GetAllUsers()
        {
            return _context.Users.ToList();
        }
    }
    
    public ActionResult Index()
    {
        var users = GetApiUsers();
        return View(users);
    }
    
    private IList<User> GetApiUsers()
    {
        const string apiBaseUrl = "http://localhost:52812/Api/";
        const string apiSuffix = "ApiExample/GetAllUsers";
    
        var client = new RestClient(apiBaseUrl);
    
        var request = new RestRequest(apiSuffix, Method.GET);
    
        var response = (RestResponse<List<User>>)client.Execute<List<User>>(request);
        return response.Data;
    }
    
    public ActionResult Index()
    {
    var users=GetApiUsers();
    返回视图(用户);
    }
    私有IList GetApiUsers()
    {
    常量字符串apiBaseUrl=”http://localhost:52812/Api/";
    常量字符串apiSuffix=“apexample/GetAllUsers”;
    var client=新的RestClient(apiBaseUrl);
    var请求=新的重新请求(apiSuffix,Method.GET);
    var response=(resresponse)client.Execute(request);
    返回响应数据;
    }
    
    d示例:

    API控制器:

    public interface IApiDTOExampleController
    {
        IEnumerable<UserDTO> GetAllUsers();
    }
    
    public class ApiDTOExampleController : ApiController, IApiDTOExampleController
    {
        private readonly IEFContext _context;
    
        public ApiDTOExampleController()
        {
            _context = new EFContext();
        }
    
        public IEnumerable<UserDTO> GetAllUsers()
        {
            return _context.Users.Select(x => new UserDTO { Id = x.Id, Name = x.Name }).ToList();
        }
    }
    
    公共接口IApiDTOExampleController
    {
    IEnumerable GetAllUsers();
    }
    公共类ApiDTOExampleController:ApicController、IApiDTOExampleController
    {
    私有只读IEFContext\u上下文;
    公共ApiDTOExampleController()
    {
    _context=新的EFContext();
    }
    公共IEnumerable GetAllUsers()
    {
    返回_context.Users.Select(x=>newuserdto{Id=x.Id,Name=x.Name}).ToList();
    }
    }
    
    调用此API的代码如下所示:

    public ActionResult IndexDTO()
    {
        var dtoUsers = GetApiDTOUsers();
        return View(dtoUsers);
    }
    
    private IList<UserDTO> GetApiDTOUsers()
    {
        const string apiBaseUrl = "http://localhost:52812/Api/";
        const string apiSuffix = "ApiDTOExample/GetAllUsers";
    
        var client = new RestClient(apiBaseUrl);
    
        var request = new RestRequest(apiSuffix, Method.GET);
    
        var response = (RestResponse<List<UserDTO>>)client.Execute<List<UserDTO>>(request);
        return response.Data; 
    }
    
    public ActionResult IndexDTO()
    {
    var dtoUsers=GetApiDTOUsers();
    返回视图(数据仓库);
    }
    私有IList GetApiDTOUsers()
    {
    常量字符串apiBaseUrl=”http://localhost:52812/Api/";
    常量字符串apiSuffix=“ApiDTOExample/GetAllUsers”;
    var client=新的RestClient(apiBaseUrl);
    var请求=新的重新请求(apiSuffix,Method.GET);
    var response=(resresponse)client.Execute(request);
    返回响应数据;
    }
    
    正如您所看到的,DTO和EF实现之间没有太大区别。。。然而,使用DTO允许您控制呼叫端需要哪些数据

    两者都可以很好地工作(在我的例子中),因此根据您的产品或城市对象,可能不需要实现DTO来消除错误(不过我建议您这样做)

    public interface IApiDTOExampleController
    {
        IEnumerable<UserDTO> GetAllUsers();
    }
    
    public class ApiDTOExampleController : ApiController, IApiDTOExampleController
    {
        private readonly IEFContext _context;
    
        public ApiDTOExampleController()
        {
            _context = new EFContext();
        }
    
        public IEnumerable<UserDTO> GetAllUsers()
        {
            return _context.Users.Select(x => new UserDTO { Id = x.Id, Name = x.Name }).ToList();
        }
    }
    
    public ActionResult IndexDTO()
    {
        var dtoUsers = GetApiDTOUsers();
        return View(dtoUsers);
    }
    
    private IList<UserDTO> GetApiDTOUsers()
    {
        const string apiBaseUrl = "http://localhost:52812/Api/";
        const string apiSuffix = "ApiDTOExample/GetAllUsers";
    
        var client = new RestClient(apiBaseUrl);
    
        var request = new RestRequest(apiSuffix, Method.GET);
    
        var response = (RestResponse<List<UserDTO>>)client.Execute<List<UserDTO>>(request);
        return response.Data; 
    }