.NET MAUI登录后传递用户信息失败,遇CS1914错误求助
.NET MAUI登录后传递用户信息到Dashboard的解决方案
问题分析
- 导航传参方式错误:直接将对象拼接在URL中无法正确传递复杂对象,Shell导航需通过参数字典传递对象。
- QueryProperty配置错误:DashboardViewModel的QueryProperty未正确指向要接收的User对象,且存在不存在的
UserLogin类型。 - 静态字段误用:试图将User模型属性设为静态导致CS1914错误,静态属性属于类而非实例,无法在对象初始化器中赋值。
- 存在SQL注入风险:直接拼接SQL语句会引发严重安全问题。
分步解决方案
1. 修复登录ViewModel的导航传参和SQL查询
修改LoginViewModel中的Login方法:
[RelayCommand] async Task Login() { SqlConnection con; SqlCommand cmd; SqlDataReader dr; con = new SqlConnection( $"Data Source={db.DatabaseServer};" + $"Initial Catalog={db.databaseName};" + $"User Id={db.DatabaseUser};" + $"Password={db.databasePass};" + $"TrustServerCertificate=True"); try { cmd = new SqlCommand(); con.Open(); cmd.Connection = con; // 替换为参数化查询,避免SQL注入 cmd.CommandText = "SELECT * FROM WeWillDoIt.accounts WHERE email = @Email AND password = @Password"; cmd.Parameters.AddWithValue("@Email", email); cmd.Parameters.AddWithValue("@Password", password); dr = cmd.ExecuteReader(); if (dr.Read()) { User userList = new User { Email = dr["email"].ToString(), Password = dr["password"].ToString(), Username = dr["username"].ToString(), Name = dr["name"].ToString(), Lastname = dr["surname"].ToString(), Country = dr["country"].ToString(), City = dr["city"].ToString(), Postcode = dr["postcode"].ToString(), Created = dr["created"].ToString() }; // 使用参数字典传递User对象 await Shell.Current.GoToAsync(nameof(Dashboard), new Dictionary<string, object> { { "User", userList } }); } else await Shell.Current.DisplayAlert("登录失败", $"无效邮箱: {email} 或密码: {password}", "确定"); } catch (Exception ex) { await Shell.Current.DisplayAlert("数据库错误", $"错误信息: {ex.Message}", "确定"); } finally { // 确保连接关闭 con?.Close(); } }
2. 修正DashboardViewModel的QueryProperty配置
替换DashboardViewModel代码:
using CommunityToolkit.Mvvm.ComponentModel; using LoginMAUI.Models; namespace LoginMAUI.ViewModel; // 配置QueryProperty,接收名为"User"的参数,绑定到User属性 [QueryProperty(nameof(User), "User")] public partial class DashboardViewModel : ObservableObject { [ObservableProperty] User user; // 计算属性,避免初始化时user为null的问题 public string DisplayUsername => User != null && !string.IsNullOrEmpty(User.Username) ? $"Username: {User.Username}" : "Username: Unknown"; }
3. 简化Dashboard页面代码
Dashboard页面无需额外字段,保持简洁:
public partial class Dashboard : ContentPage { public Dashboard(DashboardViewModel vm) { InitializeComponent(); BindingContext = vm; } }
4. 保持User模型原样(无需静态属性)
你的User模型代码是正确的,不要将属性设为静态,ObservableProperty会自动生成实例属性,避免CS1914错误:
using CommunityToolkit.Mvvm.ComponentModel; namespace LoginMAUI.Models; public partial class User : ObservableObject { [ObservableProperty] public string name; [ObservableProperty] public string lastname; [ObservableProperty] public string email; [ObservableProperty] public string username; [ObservableProperty] public string password; [ObservableProperty] public string number; [ObservableProperty] public string country; [ObservableProperty] public string city; [ObservableProperty] public string postcode; [ObservableProperty] public string created; public User() { } }
5. 在Dashboard页面绑定显示用户名
在Dashboard的XAML中绑定DisplayUsername属性:
<Label Text="{Binding DisplayUsername}" />
关键说明
- Shell导航传递复杂对象时,使用
Dictionary<string, object>作为参数,Shell会自动处理对象的序列化/反序列化。 - QueryProperty的第一个参数是ViewModel中的属性名(首字母大写,对应ObservableProperty生成的属性),第二个参数是导航时传递的参数键名。
- 永远不要直接拼接SQL语句,使用参数化查询避免SQL注入攻击。
- 静态字段不适合传递用户信息,会导致多用户场景下的数据混乱,应使用实例属性或依赖注入传递对象。
内容的提问来源于stack exchange,提问作者Maliq Dyrma
相关产品推荐
相关产品推荐

