4 回答

TA貢獻1757條經驗 獲得超7個贊
出于我的目的,似乎最整潔的解決方案是這樣的:
將 User 類拆分為基類和派生類,并添加構造函數以復制必填字段:
public class User
{
public User() { }
public User(UserDetails user)
{
this.UserId = user.UserId;
this.Name = user.Name;
this.Email = user.Email;
}
public string UserId { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
public class UserDetails : User
{
public string PasswordHash { get; set; }
}
數據訪問類將返回一個 UserDetails 對象,然后可以在返回之前對其進行轉換:
UserDetails userDetails = _dataAccess.GetUser();
User userToReturn = new User(userDetails);
也可以按照 Daniel 的建議使用自動映射器而不是構造函數方法來完成。我不喜歡這樣做,因此我問這個問題,但這似乎是最整潔的解決方案,需要最少的重復。

TA貢獻1780條經驗 獲得超4個贊
有兩種方法可以做到這一點:
使用相同的類,并且僅填充要發送的屬性。這樣做的問題是,值類型將具有默認值(屬性將作為 發送,如果這可能不準確)。
int
0
對要發送到客戶端的數據使用其他類。這基本上就是丹尼爾在評論中得到的 - 你有一個不同的模型,由客戶“查看”。
第二種選擇是最常見的。如果您使用的是 Linq,則可以使用以下命令映射值:Select()
users.Select(u => new UserModel { Name = u.Name, Email = u.Email });
基本類型不會像您希望的那樣工作。如果將派生類型強制轉換為其父類型并對其進行序列化,它仍會序列化派生類型的屬性。
以這個為例:
public class UserBase {
public string Name { get; set; }
public string Email { get; set; }
}
public class User : UserBase {
public string UserId { get; set; }
public string PasswordHash { get; set; }
}
var user = new User() {
UserId = "Secret",
PasswordHash = "Secret",
Name = "Me",
Email = "something"
};
var serialized = JsonConvert.SerializeObject((UserBase) user);
請注意,序列化時強制轉換。即便如此,結果是:
{
"UserId": "Secret",
"PasswordHash": "Secret",
"Name": "Me",
"Email": "something"
}
它仍然序列化了該類型的屬性,即使它被強制轉換為 。UserUserBase

TA貢獻1818條經驗 獲得超7個贊
如果要忽略該屬性,只需在模型中添加忽略 annotation,就像這樣,當模型序列化時,它將跳過該屬性。
[JsonIgnore]
public string PasswordHash { get; set; }
如果你想在運行時忽略(這意味著動態).Newtonsoft.Json中有一個構建函數可用
public class User
{
public string UserId { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string PasswordHash { get; set; }
//FYI ShouldSerialize_PROPERTY_NAME_HERE()
public bool ShouldSerializePasswordHash()
{
// use the condtion when it will be serlized
return (PasswordHash != this);
}
}
它被稱為“條件屬性序列化”,文檔可以在這里找到。

TA貢獻1851條經驗 獲得超3個贊
問題是你看錯了。API 即使直接與特定的數據庫實體一起工作,也不會處理實體。這里有一個關注點分離問題。您的 API 正在處理用戶實體的表示形式。實體類本身是數據庫的函數。它上面有一些只對數據庫重要的東西,重要的是,它上面的東西對你的API無關緊要。嘗試使用一個可以滿足多個不同應用程序的類是愚蠢的,并且只會導致具有嵌套依賴項的代碼變脆。
更重要的是,您將如何與此 API 交互?也就是說,如果您的API直接公開您的實體,那么使用此API的任何代碼都必須依賴于您的數據層以便它可以訪問,或者它必須實現自己的類來表示,并希望它與API實際想要的相匹配。User
User
User
現在想象一下替代方案。創建一個“通用”類庫,該類庫將在 API 和任何客戶端之間共享。在該庫中,您可以定義類似 .您的 API 僅綁定到/從 綁定,并將其來回映射到 ?,F在,您已經完全隔離了數據層??蛻舳酥恢溃ㄒ挥|及數據層的是你的API。當然,現在您可以限制向API客戶端公開的信息,只需通過構建方式即可。更好的是,如果您的應用程序需求發生變化,則可以更改,而不會像每個消費客戶端的API沖突一樣螺旋式上升。您只需修復API,客戶端就會在不知情的情況下繼續。如果確實需要進行重大更改,可以執行某些操作,例如創建類以及新版本的 API。如果不創建一個全新的表,就無法創建一個全新的表,然后這會在標識中引發沖突。UserResource
UserResource
User
UserResource
User
UserResource
User
UserResource2
User2
長話短說,使用 API 的正確方法是始終使用單獨的 DTO 類,甚至多個 DTO 類。API 永遠不應該直接使用實體類,否則你只會感到痛苦。
- 4 回答
- 0 關注
- 125 瀏覽
添加回答
舉報