ASP.NET MVC创建具有已经存在的实体的错误

时间:2018-08-06 20:54:36

标签: c# asp.net asp.net-mvc

我已经在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时,我正在尝试此操作,但是由于某些原因,此方法不起作用。

请告诉我解释是否含糊或不清楚。

谢谢

3 个答案:

答案 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。