来自控制器的格式错误的Json响应

时间:2017-10-03 14:09:03

标签: c# asp.net-core entity-framework-core

使用Asp.net核心创建Web API。我创建的端点将返回所有客户的列表(目前我只为1个客户播放了数据库)。 当我从Postman执行GET请求时,我得到了一个"无法获得任何响应"。 当我通过Chrome导航到该端点时,我看到响应,但返回的json似乎缺少括号。

[
{
    "customerId":1,
    "firstName":"John",
    "lastName":"Doe",
    "email":"johndoe@email.com",
    "address": {
        "addressId":1,
        "addressLine1":"2119 Some street",
        "addressLine2":null,
        "locality":"New York",
        "region":"New York",
        "country":"USA",
        "postCode":"10005",
        "customerId":1

我想知道格式错误的Json响应是否是Postman无法正常工作的原因。我想了解什么是错的。在我的简单例子中,我有什么问题可能会让我头疼。

我的存储库:

public class LodgingRepository : ILodgingRepository
{
    private readonly LodgingCrmContext _context;

    public LodgingRepository( LodgingCrmContext context )
    {
        _context = context;
    }

    public async Task<IEnumerable<Customer>> GetCustomersAsync( )
    {
        return await _context.Customers
            .Include( c => c.Address )
            .ToListAsync( );
    }
}

我的控制器

[Route( "api/customers" )]
public class CustomerController : Controller
{
    private readonly ILodgingRepository _lodgingRepository;

    public CustomerController( ILodgingRepository lodgingRepository )
    {
        _lodgingRepository = lodgingRepository;
    }

    [HttpGet]
    public async Task<IActionResult> GetCustomersAsync( )
    {
        return Ok( await _lodgingRepository.GetCustomersAsync( ) );
    }
}

启动

public void ConfigureServices( IServiceCollection services )
    {
        services.AddMvc( ).AddMvcOptions( options =>
            options.OutputFormatters.Add( new XmlDataContractSerializerOutputFormatter( ) ) );

        services.AddDbContext<LodgingCrmContext>( options =>
            options.UseSqlServer( Configuration.GetConnectionString( "DefaultConnection" ) ) );

        services.AddScoped<ILodgingRepository, LodgingRepository>( );
    }

public void Configure( IApplicationBuilder app, IHostingEnvironment env, LodgingCrmContext lodgingCrmContext )
    {
        if( env.IsDevelopment( ) )
        {
            app.UseDeveloperExceptionPage( );
        }

        app.UseMvc( );

        app.Run( async ( context ) => { await context.Response.WriteAsync( "Hello World!" ); } );
    }

地址实体

public class Address
{
    [Key]
    [DatabaseGenerated( DatabaseGeneratedOption.Identity )]
    public int AddressId { get; set; }

    [Required]
    [MaxLength( 254 )]
    public string AddressLine1 { get; set; }

    [MaxLength( 254 )]
    public string AddressLine2 { get; set; }

    [Required]
    [MaxLength( 60 )]
    public string Locality { get; set; }

    [Required]
    [MaxLength( 50 )]
    public string Region { get; set; }

    [Required]
    [MaxLength( 60 )]
    public string Country { get; set; }

    [Required]
    [MaxLength( 9 )]
    public string PostCode { get; set; }

    [ForeignKey( nameof(CustomerId) )]
    public int CustomerId { get; set; }

    public Customer Customer { get; set; }
}

1 个答案:

答案 0 :(得分:1)

问题是,每次响应尝试序列化地址时,它都会反弹关联的客户,然后循环重复。这会导致堆栈溢出。

如果您查看JSON,您会看到它停止,就像它必须再次为客户做的那样

创建DTO并在从服务返回时将实体映射到它们,以避免通过EF导航属性进行循环引用。

[HttpGet]
public async Task<IActionResult> GetCustomersAsync() {
    var records = await _lodgingRepository.GetCustomersAsync();
    var model = await ConvertToDTO(records); //<-- perform convertions here
    return Ok(model);
}