一直想要的,如何让MVC模型不自动添加数据库字段

这个问题可能能弱智,但是困扰了我好长时间,网上也一直搜不到,今天偶然一个机会在外国的论坛上看见这个。

首先,我想要实现的是自动绑定下拉选项,网上搜到很多方法,但是大家都是用的ViewBag(ViewData)将实例化好的DropDownList放在里面然后传递到前台,我一开始也是这么做的,但是后来莫名其妙的就出错了,说是没有实例化对象。

后来我有看了一些官方文档,其中在ASP.NET Core 表单中的标记帮助程序“https://docs.microsoft.com/zh-cn/aspnet/core/mvc/views/working-with-forms?view=aspnetcore-2.1#the-select-tag-helper”一章中,官方文档给出了正确的绑定方式,先摘要如下:

  • 为模型属性生成 select 元素和关联的 option 元素。

  • 具有 HTML 帮助程序替代项 Html.DropDownListFor 和 Html.ListBoxFor

Select Tag Helper asp-for 为 select 元素指定模型属性名称,asp-items 指定 option 元素。 例如:

HTML复制
<select asp-for="Country" asp-items="Model.Countries"></select> 

示例:

C#复制
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Collections.Generic;

namespace FormsTagHelper.ViewModels
{
    public class CountryViewModel { public string Country { get; set; } public List<SelectListItem> Countries { get; } = new List<SelectListItem> { new SelectListItem { Value = "MX", Text = "Mexico" }, new SelectListItem { Value = "CA", Text = "Canada" }, new SelectListItem { Value = "US", Text = "USA" }, }; } } 

Index 方法初始化 CountryViewModel,设置选定的国家/地区并将其传递到 Index 视图。

C#复制
public IActionResult IndexOption(int id) { var model = new CountryViewModel(); model.Country = "CA"; return View(model); } 

HTTP POST Index 方法显示选定内容:

C#复制
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index(CountryViewModel model) { if (ModelState.IsValid) { var msg = model.Country + " selected"; return RedirectToAction("IndexSuccess", new { message = msg}); } // If we got this far, something failed; redisplay form. return View(model); } 

Index 视图:

CSHTML复制
@model CountryViewModel <form asp-controller="Home" asp-action="Index" method="post">  <select asp-for="Country" asp-items="Model.Countries"></select> <br /><button type="submit">Register</button> </form> 

生成以下 HTML(选择“CA”时):

HTML复制
<form method="post" action="/"> <select id="Country" name="Country"> <option value="MX">Mexico</option> <option selected="selected" value="CA">Canada</option> <option value="US">USA</option> </select> <br /><button type="submit">Register</button> <input name="__RequestVerificationToken" type="hidden" value="<removed for brevity>" /> </form>


其中特别备注了

不建议将 ViewBag 或 ViewData 与选择标记帮助程序配合使用。 视图模型在提供 MVC 元数据方面更可靠且通常更不容易出现问题。

我才发现,其实正确的做法还是用模型还传递数据,我立马照做了,但是在提交的时候又出现了新的问题,

InvalidOperationException: The entity type 'SelectListGroup' requires a primary key to be defined.

后来百度后,在一个国外的网站上看到,说需要在模型属性中加上【NotMapped】这个Attribute,官方解释为:Denotes that a property or class should be excluded from database mapping.

如下:

      [NotMapped]
        public List<SelectListItem> Countis { get; set; } = new List<SelectListItem>();

  试验后,果然就不出错了,我理解其实出错的原因在于,没有加这个Attribute,它还想要通过Primary Key 往数据库里面插入Contis的选择后数据,加上了之后,就没有这个对应操作了。

 

回到标题,我一直想找一个Attribute,来描述一个字段,这个字段是我需要在Views中显示,但是又不需要保存在数据库中的,最典型的例子就是在注册用户时候的“确认密码”文本框,你需要它在Views中让用户来输入,但是你肯定不会保存一次密码又保存一次“确认密码“,我一直没找到对应的方法,在解决上面的问题后,我果断的将【NotMapped】这个Attribute加到了我的确认密码属性上面,果然,重新生成的数据库中没有了确认密码字段。太棒了

 

        [Display(Name = "确认密码")]
        [Required(ErrorMessage = "您需要填写{0}")]
        [StringLength(50, ErrorMessage = "{0}长度应在{2}至{1}个字符之间", MinimumLength = 6)]
        [Compare("Password",ErrorMessage ="{0}应和{1}一致")]
        [DataType(DataType.Password)]
        [NotMapped]
        public string ConfirmPassword { get; set; }

  

 

 

 

转载于:https://www.cnblogs.com/guanxing6197/p/9581309.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值