我之前检查了很多其他帖子,但我无法找到与我的问题有关的任何内容,具体如下:
我在我的项目中使用ApplicationUsers。接下来,每个用户都有一个配置文件(这是一个不同的表)。我想填写个人资料,而我正在创建"一个新的ApplicationUser在我的后台,考虑到它们通过userId相互连接。问题是这不是很有效。我使用的是ViewModels,我也为ApplicationUsers创建了一个特定的Viewmodel(UserViewModel)。
到目前为止,我可以完美地制作一个新的ApplicationUser,但是一旦我开始尝试使用与我用于ApplicationUser的那个相同的形式创建一个配置文件,事情就会开始出错。我有一些问题,我出错了(例如我的视图中只使用了1个模型(create / edit.cshtml,虽然我很确定你只能在视图中使用1个模型吗? )。
正如您在这里看到的,我的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; }
}
}
请记住,当我删除对配置文件的任何引用时,一切都已经完成了。当我开始尝试添加配置文件字段(无论是在这里还是在下面的视图中)时,问题就开始出现了。
[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);
}
@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文件(或任何模型)。请告诉我。我已经看了一段时间,但我很确定我只是误解了一些非常基本的东西?
PS:我最终得到了exceptionError所以我知道必须有一个普遍的问题,我的Try内部没有任何工作。见下图
答案 0 :(得分:0)
您应该尝试使用精益平面视图模型
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);
}