【发布时间】:2019-09-06 21:15:38
【问题描述】:
背景:
我有一个 API,它使用两个表(令牌和区域)从数据库中检索数据。每个 Token 都有一个与 Area 对象相关的 AreaID。我首先使用实体框架数据库。
问题:
当我尝试查询数据库以获取 Token(应包含对区域的引用)时。我收到一个错误:
Error getting value from 'Area' on 'System.Data.Entity.DynamicProxies.Token_51B85DEDCE118919D07024535C24194E890BF0A8499689750190733A8008D739'."
代码:
以下是 EF 创建的模型:
public partial class Token
{
public System.Guid ID { get; set; }
public System.DateTime Expiry { get; set; }
public System.Guid Reference { get; set; }
public string IPAddress { get; set; }
public string TokenValue { get; set; }
public Nullable<System.Guid> Area_ID { get; set; }
public virtual Area Area { get; set; }
}
public partial class Area
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Area()
{
this.Tokens = new HashSet<Token>();
}
public System.Guid ID { get; set; }
public string Name { get; set; }
public string UriPrefix { get; set; }
public string Description { get; set; }
public System.DateTime Created { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Token> Tokens { get; set; }
}
这是我查询数据库的地方(精简):
using (var dbContext = new APIEntities())
{
try
{
tokenObject = dbContext.Tokens.Where(t => t.TokenValue == decryptedToken).FirstOrDefault();
// the tokenObject is created but the Area property is null.
} catch (Exception ex) {
string message = ex.Message.ToString();
}
}
下面是序列化 JSON 的方法:
public HttpResponseMessage LogIntoAppWithToken()
{
string result = "";
string jsonString = "failed to get JSON";
string message = "";
try
{
var re = Request;
var headers = re.Headers;
EncryptedToken encToken = new EncryptedToken();
TokenChecker tokenChecker = new TokenChecker();
encToken.tokenValue = "";
if (headers.Contains("X-TOKEN"))
{
encToken.tokenValue = headers.GetValues("X-TOKEN").First();
}
result = tokenChecker.IsTokenValid(encToken).ToString();
Token retrievedToken = tokenChecker.GetTokenByTokenValue(encToken.tokenValue);
jsonString = JsonConvert.SerializeObject(retrievedToken);
// ERROR Here ^^
} catch (Exception ex) {
message = ex.Message.ToString();
}
return Request.CreateResponse(HttpStatusCode.OK, "Token is valid: " + result + ". " + " " + jsonString + " " + " Any error messages: " + message);
}
我尝试过的:
创建 dbContext 时我使用过:
dbContext.Configuration.ProxyCreationEnabled = false;
dbContext.Configuration.LazyLoadingEnabled = false;
在 WebApiConfig 中:
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);
在 Global.asax 的 Application_start 中:
config.Formatters.JsonFormatter
.SerializerSettings
.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
我什至尝试从 tokenObject 获取 AreaID 并查询数据库以“手动”获取区域,然后将此检索到的区域对象添加到 tokenObject(覆盖空版本):
Area areaObject = dbContext.Areas.Where(a => a.ID == tokenObject.Area_ID).FirstOrDefault();
tokenObject.Area = areaObject;
但这会导致自引用循环错误。 (这个想法更多的是用于测试而不是用作解决方案)。
我需要做什么才能检索包含一个区域作为其属性之一的令牌,然后序列化为 JSON 字符串?
编辑 1
我注意到 Token 对象现在包含 Area 对象,但 Area 对象包含一个包含 Area 的 Token?这种情况一直在继续……
根据我的设置,令牌肯定包含区域,但区域不应该包含令牌?
【问题讨论】:
标签: c# entity-framework asp.net-web-api