[c#] Json을 사용하여 Web API에서 응답을 직렬화하지 못했습니다.
ASP.NET MVC 5 Web Api로 작업하고 있습니다. 모든 사용자에게 문의하고 싶습니다.
나는 이것을 썼고 api/users
나는 이것을 받았다.
” ‘ObjectContent`1’유형이 ‘application / json; charset = utf-8’컨텐츠 유형에 대한 응답 본문을 직렬화하지 못했습니다.”
WebApiConfig에서 이미 다음 줄을 추가했습니다.
HttpConfiguration config = new HttpConfiguration();
config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
하지만 여전히 작동하지 않습니다.
반환 데이터에 대한 내 기능은 다음과 같습니다.
public IEnumerable<User> GetAll()
{
using (Database db = new Database())
{
return db.Users.ToList();
}
}
답변
Web Api (또는 해당 문제에 대한 다른 웹 서비스)에서 소비자에게 데이터를 반환하는 경우 데이터베이스에서 가져온 엔터티를 다시 전달하지 않는 것이 좋습니다. 데이터베이스가 아닌 데이터의 모양을 제어 할 수있는 모델을 사용하는 것이 훨씬 더 안정적이고 유지 관리가 쉽습니다. 이렇게하면 WebApiConfig에서 포맷터를 너무 많이 다룰 필요가 없습니다. 속성으로 자식 모델이있는 UserModel을 만들고 반환 개체에서 참조 루프를 제거 할 수 있습니다. 이것은 serializer를 훨씬 더 행복하게 만듭니다.
또한 요청에 “Accepts”헤더 만 지정하는 경우 일반적으로 포맷터 또는 지원되는 미디어 유형을 제거 할 필요가 없습니다. 그 물건을 가지고 노는 것은 때때로 일을 더 혼란스럽게 만들 수 있습니다.
예:
public class UserModel {
public string Name {get;set;}
public string Age {get;set;}
// Other properties here that do not reference another UserModel class.
}
답변
EF로 작업하는 경우 Global.asax에 아래 코드를 추가하는 것 외에
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings
.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
GlobalConfiguration.Configuration.Formatters
.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
가져 오는 것을 잊지 마세요
using System.Data.Entity;
그런 다음 자신의 EF 모델을 반환 할 수 있습니다.
그렇게 간단합니다!
답변
정답이 주어지면 한 가지 방법이지만 하나의 구성 설정으로 수정할 수 있다면 과잉입니다.
dbcontext 생성자에서 사용하는 것이 더 좋습니다.
public DbContext() // dbcontext constructor
: base("name=ConnectionStringNameFromWebConfig")
{
this.Configuration.LazyLoadingEnabled = false;
this.Configuration.ProxyCreationEnabled = false;
}
답변
이 코드를 global.asax
아래에 추가하십시오 Application_Start
.
에서 .Ignore
로 업데이트하십시오 .Serialize
. 작동해야합니다.
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize;
GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
답변
public class UserController : ApiController
{
Database db = new Database();
// construction
public UserController()
{
// Add the following code
// problem will be solved
db.Configuration.ProxyCreationEnabled = false;
}
public IEnumerable<User> GetAll()
{
return db.Users.ToList();
}
}
답변
이 코드가 마음에 들지 않습니다.
foreach(var user in db.Users)
대안으로 다음과 같이 할 수 있습니다.
var listOfUsers = db.Users.Select(r => new UserModel
{
userModel.FirstName = r.FirstName;
userModel.LastName = r.LastName;
});
return listOfUsers.ToList();
그러나 결국 Lucas Roselli의 솔루션을 사용하게되었습니다.
업데이트 : 익명 객체를 반환하여 단순화 :
var listOfUsers = db.Users.Select(r => new
{
FirstName = r.FirstName;
LastName = r.LastName;
});
return listOfUsers.ToList();
답변
이 코드를 사용하여 WebApiConfig.cs 파일에 해결했습니다.
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);