Web API - Return 模型中的一些字段
Web API - Return some fields from model
我有这个型号:
public class Quiz
{
public int Id { get; set; }
public string Title { get; set; }
public int CurrentQuestion { get; set; }
[JsonIgnore]
public virtual ICollection<Question> Questions { get; set; }
}
[JsonIgnore]
告诉 JSON 序列化器忽略这个字段(问题)。所以,我正在执行 returns 序列化无问题测验的操作。我必须执行另一个操作,该操作将 return all 字段(包括问题)。我怎样才能做到这一点 ?我需要这两个操作。
您需要稍微更改一下代码,尽管它非常简单:)
[Serializable]
public class Quiz
{
public int Id { get; set; }
public string Title { get; set; }
public int CurrentQuestion { get; set; }
}
[Serializable]
public class QuizWithQuestions : Quiz
{
public ICollection<Question> Questions { get; set; }
}
现在,如果您还想包括问题集,请使用 QuizWithQuestions
class。
我遇到了类似的问题。我的解决方案是:
默认情况下,我有禁用 LazyLoading 的 DBContext:
public EFDbContext()
:base("EFDbContext")
{
this.Configuration.ProxyCreationEnabled = true;
this.Configuration.LazyLoadingEnabled = false;
}
因此,所有导航 属性(例如 Questions
)都将是 NULL
。然后在我的 WebAPIConfig 中,我将格式化程序配置为隐藏空值:
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling
= Newtonsoft.Json.ReferenceLoopHandling.Ignore;
config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling
= Newtonsoft.Json.NullValueHandling.Ignore;
当我需要模型中所有字段的结果时,我只需在控制器中打开 LazyLoading:
repository.SwitchLazyLoading(true);
存储库中的方法:
public void SwitchLazyLoading(bool value)
{
this.context.Configuration.LazyLoadingEnabled = value;
}
我不使用 [JsonIgnore]
我只使用 [IgnoreDataMember]
请看Switches for LazyLoading with Repository pattern
最好不要 return 您的域模型来自 API。更好的方法是创建视图模型 classes 和 return 它们。
因此在您的示例中,您只需创建:
public class QuizViewModel
{
public int Id { get; set; }
public string Title { get; set; }
public int CurrentQuestion { get; set; }
}
并将其用于 return 来自您 API 的数据。
显然,在一些更大的 classes 中,创建复制所有属性的代码将是一场噩梦,但别担心 - Automapper (http://automapper.org/) 来拯救! :)
//Best put this line in app init code
Mapper.CrateMap<Quiz, QuizViewModel>();
//And in your API
var quiz = GetSomeQuiz();
return Mapper.Map<QuizViewModel>(quiz);
然后您以相同的方式创建另一个带有“问题”字段的视图模型class。
我有这个型号:
public class Quiz
{
public int Id { get; set; }
public string Title { get; set; }
public int CurrentQuestion { get; set; }
[JsonIgnore]
public virtual ICollection<Question> Questions { get; set; }
}
[JsonIgnore]
告诉 JSON 序列化器忽略这个字段(问题)。所以,我正在执行 returns 序列化无问题测验的操作。我必须执行另一个操作,该操作将 return all 字段(包括问题)。我怎样才能做到这一点 ?我需要这两个操作。
您需要稍微更改一下代码,尽管它非常简单:)
[Serializable]
public class Quiz
{
public int Id { get; set; }
public string Title { get; set; }
public int CurrentQuestion { get; set; }
}
[Serializable]
public class QuizWithQuestions : Quiz
{
public ICollection<Question> Questions { get; set; }
}
现在,如果您还想包括问题集,请使用 QuizWithQuestions
class。
我遇到了类似的问题。我的解决方案是:
默认情况下,我有禁用 LazyLoading 的 DBContext:
public EFDbContext()
:base("EFDbContext")
{
this.Configuration.ProxyCreationEnabled = true;
this.Configuration.LazyLoadingEnabled = false;
}
因此,所有导航 属性(例如 Questions
)都将是 NULL
。然后在我的 WebAPIConfig 中,我将格式化程序配置为隐藏空值:
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling
= Newtonsoft.Json.ReferenceLoopHandling.Ignore;
config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling
= Newtonsoft.Json.NullValueHandling.Ignore;
当我需要模型中所有字段的结果时,我只需在控制器中打开 LazyLoading:
repository.SwitchLazyLoading(true);
存储库中的方法:
public void SwitchLazyLoading(bool value)
{
this.context.Configuration.LazyLoadingEnabled = value;
}
我不使用 [JsonIgnore]
我只使用 [IgnoreDataMember]
请看Switches for LazyLoading with Repository pattern
最好不要 return 您的域模型来自 API。更好的方法是创建视图模型 classes 和 return 它们。
因此在您的示例中,您只需创建:
public class QuizViewModel
{
public int Id { get; set; }
public string Title { get; set; }
public int CurrentQuestion { get; set; }
}
并将其用于 return 来自您 API 的数据。
显然,在一些更大的 classes 中,创建复制所有属性的代码将是一场噩梦,但别担心 - Automapper (http://automapper.org/) 来拯救! :)
//Best put this line in app init code
Mapper.CrateMap<Quiz, QuizViewModel>();
//And in your API
var quiz = GetSomeQuiz();
return Mapper.Map<QuizViewModel>(quiz);
然后您以相同的方式创建另一个带有“问题”字段的视图模型class。