如何在没有 Json parseerror (Asp.Net Core MVC) 的情况下从 Model 到 ViewModel 获取数组的某些属性
How to get certain properties of the array from Model to ViewModel without Json parseerror (Asp.Net Core MVC)
我目前正在处理 Asp.Net Core MVC 项目并收到以下消息 class
public class Message
{
public int Id { get; set; }
public string SenderId { get; set; }
[ForeignKey("SenderId")]
public virtual User Sender { get; set; }
public string RecipientId { get; set; }
[ForeignKey("RecipientId")]
public virtual User Recipient { get; set; }
public string Content { get; set; }
public bool IsRead { get; set; }
public DateTime? DateRead { get; set; }
public DateTime MessageSent { get; set; }
public bool SenderDeleted { get; set; }
public bool RecipientDeleted { get; set; }
}
使用映射器,我得到了以下用于消息审查的 ViewModel:
public class MessageReviewViewModel
{
public int Id { get; set; }
public string SenderId { get; set; }
[ForeignKey("SenderId")]
public virtual User Sender { get; set; }
public string RecipientId { get; set; }
[ForeignKey("RecipientId")]
public virtual User Recipient { get; set; }
public string Content { get; set; }
public bool IsRead { get; set; }
public DateTime? DateRead { get; set; }
public DateTime MessageSent { get; set; }
}
现在,我实际上想要获得 Recipient 和 Sender 用户,但是我有这么简单的 MessageReviewViewModel 的原因是因为我得到了这个视图模型的列表,并且有了这个用户 json throws一个错误 & 没有它我有成功的结果。
然而,问题是,为了在收件箱视图中正确显示,我仍然需要收件人和发件人用户的某些属性(他们的主要照片 url、用户名等)。
我的映射器配置如下,以从存储库获取消息:
public async Task<IEnumerable<MessageReviewViewModel>> GetMessagesForUserByUserId(string userId)
{
var messages = await messageRepository.GetMessagesForUser(userId);
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Message, MessageReviewViewModel>();
cfg.IgnoreUnmapped();
});
IMapper mapper = config.CreateMapper();
var messageList = mapper.Map<IEnumerable<Message>, IEnumerable<MessageReviewViewModel>>(messages);
return messageList;
}
在 React 组件中(我已经在 asp.net 核心 mvc 中集成了 react.js)一旦它挂载,我就发出一个获取请求以获取如下消息列表并将 setState messagesList 设置为接收到的数组。
componentDidMount() {
const xhr = new XMLHttpRequest();
xhr.open('get', "/Messages/GetMessages", true);
xhr.onload = () => {
const data = JSON.parse(xhr.responseText);
this.setState({ messagesList: data });
console.log(this.state.messagesList);
};
xhr.send();
}
这是控制器中的动作,被调用:
[HttpGet]
public async Task<IActionResult> GetMessages()
{
var userFromRepo = await userManager.FindByNameAsync(User.Identity.Name);
var messages = await messagesService.GetMessagesForUserByUserId(userFromRepo.Id);
var sortedMessageList = messages.OrderByDescending(m => m.MessageSent);
return Json(sortedMessageList);
}
正如我所提到的,除非 MessageReviewViewModel 中没有虚拟用户发件人和虚拟用户收件人,否则一切正常。一旦我将它们写入代码,这就是我得到的错误:
可能值得一提的是,用户 class 对象(例如在我的场景中发件人和收件人)内部也有虚拟属性,我认为这可能是 [=42= 的问题] 解析这些对象,其中有其他对象为属性。
你能告诉我如何将这些属性包含在 ViewModel 中,这样映射器和 JSON 都不会抛出任何错误吗?我什至只获取对象的选定属性(例如,仅字符串用户名、mainphoto url 等)。
也可以,如果有任何 Json 方法,这将解决 ViewModel
中包含的虚拟用户的 parseError
发现mapper也可以配置成用户需要的级别后想通了
消息模型如下
public class Message
{
public int Id { get; set; }
public string SenderId { get; set; }
[ForeignKey("SenderId")]
public virtual User Sender { get; set; }
public string RecipientId { get; set; }
[ForeignKey("RecipientId")]
public virtual User Recipient { get; set; }
public string Content { get; set; }
public bool IsRead { get; set; }
public DateTime? DateRead { get; set; }
public DateTime MessageSent { get; set; }
public bool SenderDeleted { get; set; }
public bool RecipientDeleted { get; set; }
}
并且 MessageReviewViewModel 更改为以下内容:
public class MessageReviewViewModel
{
public int Id { get; set; }
public string SenderId { get; set; }
public string SenderUsername { get; set; }
public string SenderMainPhotoUrl { get; set; }
public string RecipientId { get; set; }
[ForeignKey("RecipientId")]
public string RecipientUsername { get; set; }
public string RecipientMainPhotoUrl { get; set; }
public string Content { get; set; }
public bool IsRead { get; set; }
public DateTime? DateRead { get; set; }
public DateTime MessageSent { get; set; }
}
仅映射器需要如下配置:
public async Task<IEnumerable<MessageReviewViewModel>> GetMessagesForUserByUserId(string userId)
{
var messages = await messageRepository.GetMessagesForUser(userId);
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Message, MessageReviewViewModel>()
.ForMember(destination=>destination.RecipientUsername,map=>map.MapFrom(
source=>source.Recipient.UserName)) //gets only string for username instead of whole User model
.ForMember(destination=> destination.RecipientMainPhotoUrl,map=>map.MapFrom(
source=>source.Recipient.MainProfilePicture)) //gets only string for profile picture instead of whole User model
.ForMember(destination=>destination.SenderUsername,map=>map.MapFrom(
source=>source.Sender.UserName))
.ForMember(destination=>destination.SenderMainPhotoUrl,map=>map.MapFrom(
source=>source.Sender.MainProfilePicture));
cfg.IgnoreUnmapped();
});
IMapper mapper = config.CreateMapper();
var messageList = mapper.Map<IEnumerable<Message>, IEnumerable<MessageReviewViewModel>>(messages);
return messageList;
}
由于现在所有接收到的数据都是字符串,Json解析没有问题
我目前正在处理 Asp.Net Core MVC 项目并收到以下消息 class
public class Message
{
public int Id { get; set; }
public string SenderId { get; set; }
[ForeignKey("SenderId")]
public virtual User Sender { get; set; }
public string RecipientId { get; set; }
[ForeignKey("RecipientId")]
public virtual User Recipient { get; set; }
public string Content { get; set; }
public bool IsRead { get; set; }
public DateTime? DateRead { get; set; }
public DateTime MessageSent { get; set; }
public bool SenderDeleted { get; set; }
public bool RecipientDeleted { get; set; }
}
使用映射器,我得到了以下用于消息审查的 ViewModel:
public class MessageReviewViewModel
{
public int Id { get; set; }
public string SenderId { get; set; }
[ForeignKey("SenderId")]
public virtual User Sender { get; set; }
public string RecipientId { get; set; }
[ForeignKey("RecipientId")]
public virtual User Recipient { get; set; }
public string Content { get; set; }
public bool IsRead { get; set; }
public DateTime? DateRead { get; set; }
public DateTime MessageSent { get; set; }
}
现在,我实际上想要获得 Recipient 和 Sender 用户,但是我有这么简单的 MessageReviewViewModel 的原因是因为我得到了这个视图模型的列表,并且有了这个用户 json throws一个错误 & 没有它我有成功的结果。 然而,问题是,为了在收件箱视图中正确显示,我仍然需要收件人和发件人用户的某些属性(他们的主要照片 url、用户名等)。
我的映射器配置如下,以从存储库获取消息:
public async Task<IEnumerable<MessageReviewViewModel>> GetMessagesForUserByUserId(string userId)
{
var messages = await messageRepository.GetMessagesForUser(userId);
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Message, MessageReviewViewModel>();
cfg.IgnoreUnmapped();
});
IMapper mapper = config.CreateMapper();
var messageList = mapper.Map<IEnumerable<Message>, IEnumerable<MessageReviewViewModel>>(messages);
return messageList;
}
在 React 组件中(我已经在 asp.net 核心 mvc 中集成了 react.js)一旦它挂载,我就发出一个获取请求以获取如下消息列表并将 setState messagesList 设置为接收到的数组。
componentDidMount() {
const xhr = new XMLHttpRequest();
xhr.open('get', "/Messages/GetMessages", true);
xhr.onload = () => {
const data = JSON.parse(xhr.responseText);
this.setState({ messagesList: data });
console.log(this.state.messagesList);
};
xhr.send();
}
这是控制器中的动作,被调用:
[HttpGet]
public async Task<IActionResult> GetMessages()
{
var userFromRepo = await userManager.FindByNameAsync(User.Identity.Name);
var messages = await messagesService.GetMessagesForUserByUserId(userFromRepo.Id);
var sortedMessageList = messages.OrderByDescending(m => m.MessageSent);
return Json(sortedMessageList);
}
正如我所提到的,除非 MessageReviewViewModel 中没有虚拟用户发件人和虚拟用户收件人,否则一切正常。一旦我将它们写入代码,这就是我得到的错误:
可能值得一提的是,用户 class 对象(例如在我的场景中发件人和收件人)内部也有虚拟属性,我认为这可能是 [=42= 的问题] 解析这些对象,其中有其他对象为属性。 你能告诉我如何将这些属性包含在 ViewModel 中,这样映射器和 JSON 都不会抛出任何错误吗?我什至只获取对象的选定属性(例如,仅字符串用户名、mainphoto url 等)。 也可以,如果有任何 Json 方法,这将解决 ViewModel
中包含的虚拟用户的 parseError发现mapper也可以配置成用户需要的级别后想通了
消息模型如下
public class Message
{
public int Id { get; set; }
public string SenderId { get; set; }
[ForeignKey("SenderId")]
public virtual User Sender { get; set; }
public string RecipientId { get; set; }
[ForeignKey("RecipientId")]
public virtual User Recipient { get; set; }
public string Content { get; set; }
public bool IsRead { get; set; }
public DateTime? DateRead { get; set; }
public DateTime MessageSent { get; set; }
public bool SenderDeleted { get; set; }
public bool RecipientDeleted { get; set; }
}
并且 MessageReviewViewModel 更改为以下内容:
public class MessageReviewViewModel
{
public int Id { get; set; }
public string SenderId { get; set; }
public string SenderUsername { get; set; }
public string SenderMainPhotoUrl { get; set; }
public string RecipientId { get; set; }
[ForeignKey("RecipientId")]
public string RecipientUsername { get; set; }
public string RecipientMainPhotoUrl { get; set; }
public string Content { get; set; }
public bool IsRead { get; set; }
public DateTime? DateRead { get; set; }
public DateTime MessageSent { get; set; }
}
仅映射器需要如下配置:
public async Task<IEnumerable<MessageReviewViewModel>> GetMessagesForUserByUserId(string userId)
{
var messages = await messageRepository.GetMessagesForUser(userId);
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Message, MessageReviewViewModel>()
.ForMember(destination=>destination.RecipientUsername,map=>map.MapFrom(
source=>source.Recipient.UserName)) //gets only string for username instead of whole User model
.ForMember(destination=> destination.RecipientMainPhotoUrl,map=>map.MapFrom(
source=>source.Recipient.MainProfilePicture)) //gets only string for profile picture instead of whole User model
.ForMember(destination=>destination.SenderUsername,map=>map.MapFrom(
source=>source.Sender.UserName))
.ForMember(destination=>destination.SenderMainPhotoUrl,map=>map.MapFrom(
source=>source.Sender.MainProfilePicture));
cfg.IgnoreUnmapped();
});
IMapper mapper = config.CreateMapper();
var messageList = mapper.Map<IEnumerable<Message>, IEnumerable<MessageReviewViewModel>>(messages);
return messageList;
}
由于现在所有接收到的数据都是字符串,Json解析没有问题