我想用一张表格填写多张表格

本文关键字:表格 张表格 一张 | 更新日期: 2023-09-27 18:28:32

我以前检查过很多其他线程,但我真的找不到任何特定于我的问题的东西,如下所示:

我正在与ApplicationUsers合作我的项目。除此之外,每个用户都有一个配置文件(这是一个不同的表)。考虑到他们通过userId相互连接,我想在后台"创建"新ApplicationUser时填写个人资料。问题是,这并不完全奏效。我使用的是ViewModels,我还为ApplicationUsers制作了一个特定的Viewmodel(UserViewModel)。

到目前为止,我可以制作一个新的ApplicationUser,但一旦我开始尝试使用与我为ApplicationUser使用的表单相同的表单创建配置文件,事情就开始出错了。我有一些错误的预感(例如,在我的视图中只使用了一个模型(create/edit.cshtml,尽管我很确定在视图中创建时只能使用一个模型?)。

下面是我的用户视图模型(UserViewModel.cs)

正如你在这里看到的,我的UserViewModel有一个虚拟属性Profile,它应该能够与用户一起创建配置文件?或者也许我已经大错特错了。

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using App.Models;
using App.Models.ViewModels;
namespace App.Models.Identity.ViewModels
{
    public class UserViewModel
    {
        public string UserId { get; set; }
        public string UserName { get; set; }
        public string Email { get; set; }  
        public virtual Profile Profile { get; set; }
    }
}

以下是我的编辑函数(UserController.cs)

请记住,当我删除对配置文件的任何引用时,一切都已经很正常了。当我开始尝试添加配置文件字段(无论是在这里还是在下面的视图中)时,问题就开始出现了。

        [HttpGet]
        public IActionResult Edit(string id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(400);
            }
            var model = _kletsContext.Users.FirstOrDefault(m => m.Id == id);
            var profile = _kletsContext.Profiles.FirstOrDefault(m => m.UserId == model.Id);
            if(model == null)
            {
                return RedirectToAction("Index");
            }
            var viewModel = new UserViewModel
            {
                UserId = model.Id,
                UserName = model.UserName,
                Email = model.Email,
            };
            return View(viewModel);
        }
    [HttpPost]
    [ValidateAntiForgeryToken]
    public IActionResult Edit(UserViewModel model, Profile profile)
    {
        UserViewModel viewModel = null;
        try 
        {
            if(!ModelState.IsValid)
                throw new Exception("The User model is not valid!");
            var originalModel = _kletsContext.Users.FirstOrDefault(m => m.Id == model.UserId);
            var originalProfile = _kletsContext.Profiles.FirstOrDefault(m => m.UserId == model.UserId);
            if(originalModel == null)
                throw new Exception("The existing User: " + model.UserName + " doesn't exists anymore!");
            originalModel.UserName = model.UserName;
            originalModel.Email = model.Email;
            originalProfile.Age = profile.Age;

            _kletsContext.Users.Attach(originalModel);
            _kletsContext.Profiles.Attach(profile);
            _kletsContext.Entry(originalModel).State = EntityState.Modified;
            _kletsContext.Entry(profile).State = EntityState.Modified;
            if (_kletsContext.SaveChanges() == 0)
            {
               throw new Exception("The User model could not be saved!");
            }
            return RedirectToAction("Index");
        }
        catch(Exception ex)
        {
            ModelState.AddModelError(string.Empty, "Unable to save changes.");
            viewModel = new UserViewModel
            {
                UserId = model.UserId,
                UserName = model.UserName,
                Email = model.Email,
            };    
        }
        return View(viewModel);
    }

下面是我的Edit.cshtml:

@model App.Models.Identity.ViewModels.UserViewModel
@{
    ViewBag.Title = "User";
    ViewBag.SubTitle = "Nieuwe";
    ViewBag.Description = "Aanmaak van een nieuwe User";
    Layout = "~/Areas/Backoffice/Views/Shared/_Layout.cshtml";
}
<div class="row">
    <div class="col-xs-12">
        <div class="panel panel-default">
            <div class="panel-heading">
                Aanmaak van een nieuwe User
            </div>
            <div class="panel-body">
                @using (Html.BeginForm())
                {
                    @Html.AntiForgeryToken()
                    @Html.HiddenFor(m => m.UserId)
                    <fieldset>
                        <legend class="hidden">Aanmaak van een nieuwe User</legend>
                        @Html.ValidationSummary("", new {@class="alert-danger"})
                        <div class="form-group">
                            @Html.LabelFor(m => m.UserName)
                            @Html.TextBoxFor(m => m.UserName, new { @class= "form-control" })
                        </div>
                        <div class="form-group">
                            @Html.LabelFor(m => m.Email)
                            @Html.TextBoxFor(m => m.Email, new { @class= "form-control" })
                        </div>
                        <div class="form-group">
                            @Html.LabelFor(m => m.Profile.Age)
                            @Html.TextBoxFor(m => m.Profile.Age, new { @class= "form-control" })
                        </div>
                       @Html.ActionLink("Terug naar het overzicht", "Index", new { }, new { @class= "btn btn-default" })
                        <input type="submit" value="Save" class="btn btn-primary" />
                    </fieldset>
                }
            </div>
        </div>
    </div>      
</div>

额外:如果需要,我会添加ProfileViewModel,或DBContext文件(或任何模型)。请告诉我。我已经看了一段时间了,但我很确定我只是误解了一些非常基本的东西?

附言:我最终得到了exceptionError,所以我知道肯定有一个普遍的问题,我的Try内部什么都不起作用。参见下方的图片

https://gyazo.com/399e59d7d3cfdab2141726fc49ad6786

我想用一张表格填写多张表格

您应该尝试使用精简平面视图模型

public class UserProfileViewModel
{
    public string UserId { get; set; }
    public string UserName { get; set; }
    public string Email { get; set; }  
    public int Age { get; set; }
}

以及在您的GET操作中

public ActionResult Edit(string id)
{
   var model = _kletsContext.Users.FirstOrDefault(m => m.Id == id);
   var profile = _kletsContext.Profiles.FirstOrDefault(m => m.UserId == model.Id);
   if(model == null)
   {
       return RedirectToAction("Index");
   }
   var vm = new UserProfileViewModel
   {
       UserId = model.Id,
       UserName = model.UserName,
       Email = model.Email,
       Age = profile.Age
   };
   return View(vm);
}

您的剃刀视图将被强键入此视图模型

@model YourNamespaceHere.UserProfileViewModel
@using(Html.BeginForm())
{
  <label>UserName</label>
  @Html.TextBoxFor(s=>s.UserName)
  <label>Email</label>
  @Html.TextBoxFor(s=>s.Email)
  <label>Age</label>
  @Html.TextBoxFor(s=>s.Age)
  @Html.HiddenFor(s=>s.UserId)
  <input type="submit" />
}

在你的HttpPost操作中,我们将使用这个视图模型作为方法参数,发布的表单将通过默认的模型绑定器转换为这个类的对象。

[HttpPost]
public ActionResult Edit(UserProfileViewModel model)
{
  if(ModelState.IsValid)
  {
     var u = _kletsContext.Users.FirstOrDefault(m => m.Id == model.UserId);
     var p= _kletsContext.Profiles.FirstOrDefault(m => m.UserId == model.UserId);
     //Set the new values
     u.Email = model.Email;
     if(p!=null)
     {
        p.Age=model.Age;
        _kletsContext.Entry(p).State = EntityState.Modified;
     }
     else
     {
        // to do  :Create a new profile record
     }
     _kletsContext.Entry(u).State = EntityState.Modified;
    _kletsContext.SaveChanges();
     // to redirect to some success page
  }
  return View(model);
}