我已经在Web表单中完成了此操作,但是很难在ASP.NET MVC中尝试此操作。我正在使用Visual Studio 2017。
我正在尝试创建一个实体,如果该实体已经存在,且具有ID号,我想发出类似“相同ID存在!”的警报。并停留在同一页面上。
但是,如果id不存在,它将直接转到具有表单的另一个页面(我想是重定向),该表单具有构成另一个实体的形式,该实体是第一个实体的详细实体。
现在我所能想到的就是当表单 加载(在javascript上,也许是..),因为与网络表单不同,后台代码未与视图集成,并且在插入相同的ID时使布尔值为true, 但是我只是无法解决这个问题,应该有一个更好的方法。
我已经阅读了有关Web-api的内容,并愿意尝试使用该方法,但不知道Web-apis如何使我能够做到这一点。
public ActionResult InsertDetail()
{
string poN = Request.Form["entityNum"];
var thisEntty = _context.entityDB.FirstOrDefault(p => p.Entity.Equals(entityNum));
if (thisEntity != null) // same entity exists!
{
ViewBag.Javscript = "<script language='javascript' type='text/javascript'>alert('Data Already Exists');</script>";
return RedirectToAction("Insert");
}
}
这是我尝试过的代码,所以我从InsertAction中创建了一个表单,并且在调用insertDetail时,我正在尝试此操作,但是由于某些原因,此方法不起作用。
请告诉我解释是否含糊或不清楚。
谢谢
答案 0 :(得分:3)
在不了解您的设置或对MVC的当前了解的情况下,我只能分享一种通用方法。从Web Forms到MVC,需要进行范式转换,最终将使您成为一个更好的程序员。
首先,您通过NuGet在项目中安装Entity Framework。
接下来,您将创建一个模型,其中包含实体所需的每个字段。在此示例中,我将其命名为“成员”,并提供ID,姓名,电子邮件和地址:
public sealed class Member
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Address { get; set; }
}
通过将字段的类型设置为“ int”并将其命名为“ Id”,实体框架将自动使该字段成为PRIMARY KEY和AUTO NUMBER,而无需进行任何配置。
接下来,您将此实体添加到ApplicationDbContext类:
public DbSet<Member> Members { get; set; }
在实际项目中通常如此,您的表单仅会收集您实体中的某些字段。在此示例中,我只想收集“名称”和“电子邮件”,并留待用户稍后填写该地址。为此,您创建一个视图模型,该模型仅负责收集您希望用户提供的数据。为了使事情保持井井有条,我将创建一个单独的文件夹“ ViewModels”,并将所有视图模型保存在其中:
public sealed class MemberViewModel
{
public int? Id { get; set;}
[Required]
public string Name { get; set; }
[Required]
[EmailAddress]
public string Email { get; set; }
}
通过在视图模型中使ID为空,您可以使用相同的 用于创建新成员或更新现有成员的视图模型 会员。
根据经验,还可以使用数据注释来修饰视图模型以便进行验证。
在验证数据之前,视图模型有责任 将其传递给实体模型而不是实体模型本身。 为什么?关注点分离:通常是重要的实践 在Web窗体编程中被忽略。
转到视图(应命名为InsertDetail),然后在视图顶部添加视图模型:
@model ViewModel.MemberViewModel
现在,您已经基于视图模型创建了一个强类型视图。尽管不是必需的,但是您现在可以使用HTML助手将字段添加到视图中,如下所示:
@Html.TextBoxFor(m => m.Email, new { @class = "form-control", autofocus = "", placeholder = "Email" })
您可能还决定使用隐藏字段添加Id,但是如果您仅使用表单将数据插入表中,则最好将Id字段留空,因为这将导致其值成为NULL。但是,如果您决定将ID添加为隐藏字段,则可以通过以下方式进行操作:
@Html.HiddenFor(m => m.Id)
要在页面顶部显示验证错误,请在“ form”标签或BeginForm HTML帮助器内但在任何表单字段之前添加以下内容:
@Html.ValidationSummary("", new { @class = "text-danger" })
为防止黑客欺骗表单,请在验证摘要之前添加以下行:
@Html.AntiForgeryToken()
现在转到您的控制器。您无需重定向其他任何地方即可执行插入过程。您可以处理控制器中的所有内容。
public ActionResult InsertDetail(MemberViewModel model)
{
if (ModelState.IsValid)
{
// Get context (this should be done through a repository but let's focus)
using (var ctx = new ApplicationDbContext())
{
var member = new Member();
if (model.Id == null)
{
// Insert Member
member.Name = model.Name;
member.Email = model.Email;
ctx.Members.Add(member);
}
else
{
// Check if Id already exists
int memberId = 0;
bool result = int.TryParse(model.Id.ToString(), out memberId);
member = ctx.Members.FirstOrDefault(x => x.Id == memberId);
if (member != null) // this member already exists
{
// You can decide to throw an error or update the entity. Let's throw error
ModelState.AddModelError("", "Member Already Exists");
return View(model);
}
}
}
}
// If you get here then there is a validation error
return View(model);
}
答案 1 :(得分:0)
您可以利用MVC ModelState中的内置错误处理。
因此,在控制器上,您需要在模型上设置错误并返回相同的视图:
public ActionResult InsertDetail()
{
string poN = Request.Form["entityNum"];
var thisEntty = _context.entityDB.FirstOrDefault(p => p.Entity.Equals(entityNum));
if (thisEntity != null) // same entity exists!
{
ModelState.AddModelError("", "Data Already Exists");
return View("Insert");
}
}
在视图标记上,您可以具有用于自定义错误处理的js。在这种情况下,您想发出警报,因此以下代码仅在出现错误时运行,捕获所有错误并显示:
<script type="text/javascript">
@if (!ViewContext.ViewData.ModelState.IsValid)
{
var sb = new System.Text.StringBuilder();
foreach (var modelState in ViewContext.ViewData.ModelState.Values)
{
foreach (var error in modelState.Errors)
{
sb.Append(error.ErrorMessage);
sb.Append("\\n");
}
}
@:alert('@sb.ToString()');
}
</script>
答案 2 :(得分:0)
如果设置为标识的主键和其他唯一约束不重复,请确保传递的主键为0。