Programing

Web API에서 응답을 직렬화하지 못했습니다.

lottogame 2020. 9. 17. 18:47
반응형

Web API에서 응답을 직렬화하지 못했습니다.


ASP.NET MVC 웹 API에서 작업 중이 었는데이 오류가 발생했습니다.

'ObjectContent`1'유형이 'application / xml'컨텐츠 유형에 대한 응답 본문을 직렬화하지 못했습니다. charset = utf-8 '입니다.

내 컨트롤러는 다음과 같습니다.

public Employee GetEmployees()
{
    Employee employees = db.Employees.First();
    return employees;
}

이 오류가 발생하는 이유는 무엇입니까?


나에게 이것은 순환 참조의 문제였습니다.

받아 들여진 대답은 JSON 포맷터의 동작 만 변경하기 때문에 저에게 효과가 없었지만 브라우저에서 서비스를 호출 할 때 XML을 얻었습니다.

이 문제를 해결하기 위해 XML을 끄고 JSON 만 반환하도록했습니다.

Global.asax 파일에서 Application_Start 메서드 맨 위에 다음 줄을 추가합니다.

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);

이제 JSON 결과 만 반환됩니다. XML 결과가 필요한 경우 다른 솔루션을 찾아야합니다.


global.asax 파일의 Application_start () 메서드에 다음 줄을 추가합니다.

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;

도움이 되었기를 바랍니다.


나는 같은 문제가 있습니다. 그리고 나는 그것을 해결했습니다. 기본 생성자를 DTO 클래스에 넣었습니다.

전의:

public class User
{
    public User()
    {
    }
}

당신과 함께 일하기를 바랍니다!


이것을 생성자에 넣으십시오. 이것이 문제를 해결하기를 바랍니다.

    public MyController()
    {

        db.Configuration.ProxyCreationEnabled = false;
    }

이에 대한 두 가지 해결책을 찾았습니다. 구현하기 가장 쉬운 첫 번째 방법은 IEnumerables, ICollections를 List 유형으로 변경하는 것입니다. WebAPI는이 개체를 직렬화 할 수 있지만 인터페이스 유형을 직렬화 할 수는 없습니다.

public class Store
{

  [StringLength(5)]
    public string Zip5 { get; set; }

    public virtual List<StoreReport> StoreReports { get; set; }  //use a list here
 }

다른 옵션은 네이티브 JSON 시리얼 라이저를 사용하지 않고 WebApi Config의 Register 메서드에서이 재정의를 실행하는 것입니다.

        var json = config.Formatters.JsonFormatter;
        json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
        config.Formatters.Remove(config.Formatters.XmlFormatter);

해결책은 간단합니다.

LINQ 쿼리 후에 .ToList () (또는 필요한 경우 ToDictionary)를 추가합니다.

데이터의 지연로드보다 빠른로드를 수행합니다.


**이 버그는 클라이언트 측에서 web api / wcf / ... 요청에서 호출 할 때 발생하지만 부작용으로 include 키워드로 의존 관계를 포함해야합니다. **

public CustomerPortalContext()
            : base("Name=CustomerPortalContext")
        {
            base.Configuration.ProxyCreationEnabled = false;
        }

If you are working with EF, besides adding the code below on Global.asax

            GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
        GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);          

Dont`t forget to import

using System.Data.Entity;

Then you can return your own EF Models


please check the web api documentation for this problem, Handling Circular Object References

Regards


If you use web api with Entity Framework, a solution can be Failed to serialize the response in Web API with Json

Basically, you need to create a model corresponding to each EF model, this removes dependencies between classes and allow easy serialization.

Code: (taken from the referenced link)

Create a UserModel

public class UserModel
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

Change my method GetAll()

public IEnumerable<UserModel> GetAll()
{
    using (Database db = new Database ())
    {
        List<UserModel> listOfUsers = new List<UserModel>();
        UserModel userModel = new UserModel();
        foreach(var user in db.Users)
        {
           userModel.FirstName = user.FirstName;
           userModel.LastName = user.LastName;
           listOfUsers.Add(userModel);
        }
        IEnumerable<UserModel> users = listOfUsers;

        return users;
    }
}

but if you found this problem with other entities/classes, you have to create a new DTO for each class, and if you have a lot of them, you can find a problem, also I think that create a DTO only for solving this problem is no the best way...

Did you try this?

var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = 
Newtonsoft.Json.PreserveReferencesHandling.All;

Regards


hmmm, Following may help.

I was getting the same exception, and in my case I was passing the actual poco entity created for entity code first. Since, it contains relation with other entities, I just created the viewmapper/dto entity on top of it to return.

It works fine now.

Poco Entity:

public class Tag
{
public int Id{get;set;}
public string Title{get;set;}
public IList<Location> Locations{get;set;}
}

ViewMapper/Dto

public class TagResultsViewMapper
{
public int Id{get;set;}
public string Title{get;set;}
//just remove the following relationship 
//public IList<Location> Locations{get;set;}
}

Default Entity 6 use XML to apis, in your project, find the file "Global.asax" File and add this line:

GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);

This line remove the XML Formatter.


Your question is quite similar to mine. You must not return data from database directly. For this, you must create Model and associate data you want show.

In my example, There are data about User that Json couldn't serialize, I had create a userModel and, in my API, I return userModel instead User from database.

The logic of convert or associate data between User and UserModel must be in API.

Failed to serialize the response in Web API with Json


This was the specific error I was getting back from my odata Web API call:

The 'ObjectContent`1' type failed to serialize the response 
body for content type 'application/json; odata.metadata=minimal'.

I finally figured out that my dbContext class had a poorly formatted table name being assigned in onModelCreating.. so the SqlClient was dying looking for a table that didn't exist in my db!!

참고URL : https://stackoverflow.com/questions/12641386/failed-to-serialize-the-response-in-web-api

반응형