ASP.NET Core MVC 5中如何基于模型的一个属性为另一个属性赋值
问题根因分析
- 第一,视图中没有提交
Bmonth字段的值,模型绑定过程根本不会触发你写在Bmonth的setter里的逻辑,你写的判断代码全程未执行。 - 第二,即使
Bmonth的setter被触发,模型绑定默认按类中属性定义的顺序赋值,你的Bmonth定义在Blongmonth前面,赋值Bmonth的时候Blongmonth还是默认值null,所有判断都走else分支,自然赋值为0。 - 第三,你写的SQL语句只是查询语句,不是触发器逻辑,而且CASE分支中同时返回数字1和字符串'False',类型不兼容,执行自然会出错。
可行解决方案
方案1:修改模型属性逻辑(推荐,无需改控制器代码)
把计算逻辑写到Blongmonth的setter里,每次Blongmonth赋值的时候自动计算Bmonth的值,修改后的模型代码:
public class Bdgfixmonth { [Key] public int Counter { get; set; } [Required] public int Byear { get; set; } [Required] public string Bbudget { get; set; } [Required] public int Bmonth { get; set; } // 改为自动属性即可 private string _blongmonth; [Required] public string Blongmonth { get => _blongmonth; set { _blongmonth = value; // 用.NET内置的月份解析方法,无需手写大量if判断 if (DateTime.TryParseExact(value, "MMMM", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out var date)) { Bmonth = date.Month; } else { Bmonth = 0; } } } [Required] public int Closed { get; set; } [Required] public string Current { get; set; } }
该方案不需要修改控制器和视图的现有代码,只要提交了Blongmonth的值就会自动计算Bmonth。
方案2:在控制器的Create方法中处理
如果不想修改模型代码,可在接收提交数据的Action里手动赋值,示例代码:
[HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Create(Bdgfixmonth model) { // 手动计算并赋值Bmonth if (DateTime.TryParseExact(model.Blongmonth, "MMMM", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out var date)) { model.Bmonth = date.Month; } if (ModelState.IsValid) { // 原有存入数据库的逻辑 _context.Add(model); await _context.SaveChangesAsync(); return RedirectToAction(nameof(Index)); } return View(model); }
关于SQL触发器的补充
如果你要走触发器方案,需要编写INSERT/UPDATE触发器而非查询语句,示例:
CREATE TRIGGER trg_UpdateBmonth ON bdgfixmonth AFTER INSERT, UPDATE AS BEGIN UPDATE b SET b.bmonth = CASE i.blongmonth WHEN 'January' THEN 1 WHEN 'February' THEN 2 WHEN 'March' THEN 3 WHEN 'April' THEN 4 WHEN 'May' THEN 5 WHEN 'June' THEN 6 WHEN 'July' THEN 7 WHEN 'August' THEN 8 WHEN 'September' THEN 9 WHEN 'October' THEN 10 WHEN 'November' THEN 11 WHEN 'December' THEN 12 ELSE 0 END FROM bdgfixmonth b INNER JOIN inserted i ON b.Counter = i.Counter END
内容的提问来源于stack exchange,提问作者chdev
相关产品推荐
相关产品推荐

