[英]View using DTO - ASP.NET MVC
I'm fairly new to MVC and I've been trying to create a view using a DTO as the Model Class, but it seems to be using the Data Context class I use for my Models, even though I am clearing the selection when I am creating the view.我对 MVC 还很陌生,我一直在尝试使用 DTO 作为模型类来创建视图,但它似乎正在使用我用于模型的数据上下文类,即使我在清除选择时正在创建视图。
This issue seems to be causing a NullReferenceException which is caused by the following exception being thrown and the view not having any returned to it.此问题似乎导致 NullReferenceException,这是由引发以下异常并且视图未返回任何异常引起的。
ITSSkillsDatabase.Models.PersonSkillSetsDTO: : EntityType 'PersonSkillSetsDTO' has no key defined. Define the key for this EntityType.
PersonSkillSets: EntityType: EntitySet 'PersonSkillSets' is based on type 'PersonSkillSetsDTO' that has no keys defined.
My DTO:我的 DTO:
namespace ITSSkillsDatabase.Models
{
public class PersonSkillSetsDTO
{
public int IDSkillset { get; set; }
public int IDCategory { get; set; }
public string Product { get; set; }
public string P_Version { get; set; }
public string Notes { get; set; }
public int PersonSkillsID { get; set; }
public int IDPerson { get; set; }
public int Score { get; set; }
public DateTime ScoreDate { get; set; }
public int TargetScore { get; set; }
public DateTime TargetDate { get; set; }
public DateTime RefresherDate { get; set; }
}
}
Controller method:控制器方法:
public ActionResult SkillSets(int? id)
{
try
{
if (id == null)
{
return HttpNotFound();
}
var viewModel = (from a in db.SkillSets
join c in db.PersonSkills on a.IDSkillset equals c.IDSkillSet
where c.IDPerson == id
select new Models.PersonSkillSetsDTO
{
IDSkillset = a.IDSkillset,
IDCategory = a.IDCategory,
Product = a.Product,
P_Version = a.P_Version,
Notes = a.Notes,
PersonSkillsID = c.PersonSkillsID,
IDPerson = c.IDPerson,
Score = c.Score,
ScoreDate = c.ScoreDate,
TargetScore = c.TargetScore,
TargetDate = c.TargetDate,
RefresherDate = c.RefresherDate
}).ToList();
return View(viewModel);
}
catch
{
return View(); //this is where the NullReferenceException is thrown
}
}
These are the settings when I'm creating the view:这些是我创建视图时的设置:
I realise I can get rid of the NullReferenceException by checking for null values, but I don't have any idea how to fix the issue with my DTO.我意识到我可以通过检查空值来摆脱 NullReferenceException,但我不知道如何解决我的 DTO 问题。
I am going to try to explain using a ViewModel/DTO to create a Form and POST back.我将尝试解释如何使用 ViewModel/DTO 创建一个表单并回传。
ViewModels are outside of the Database Context, So if you are using a ViewModel you have to Map your data from ViewModel to Model and Model to ViewModel. ViewModel 位于数据库上下文之外,因此如果您使用的是 ViewModel,则必须将数据从 ViewModel 映射到 Model,并将 Model 映射到 ViewModel。
So if you are reading from Database所以如果你从数据库中读取
If you are writing to the database如果您正在写入数据库
let's say you have a DTO,假设你有一个 DTO,
public class CountryDTO
{
public int CountryId { get; set; }
[Display(Name = "Country Name")]
[Required(ErrorMessage = "This field is required")]
public string CountryName { get; set; }
[Display(Name = "Latitude")]
[Required(ErrorMessage = "This field is required")]
public double CentralLat { get; set; }
[Display(Name = "Longitude")]
[Required(ErrorMessage = "This field is required")]
public double CentralLang { get; set; }
[Display(Name = "GMT Offset")]
[Required(ErrorMessage = "This field is required")]
public double GMTOffSet { get; set; }
[Display(Name = "Currency")]
[Required(ErrorMessage = "This field is required")]
public string Currency { get; set; }
}
Create a controller ie CountryController
and you have a Views Folder Country
, Right Click Country Folder Add
--> View
, Name it CreateCountry
and Select Model to be CountryDTO
创建一个控制器,即
CountryController
并且您有一个 Views Folder Country
,右键单击 Country Folder Add
--> View
,将其命名为CreateCountry
并选择模型为CountryDTO
You can't select DataContext here , because DTO is not part of the Context您不能在此处选择 DataContext ,因为 DTO 不是 Context 的一部分
This will create your view with Fields from the DTO.这将使用来自 DTO 的字段创建您的视图。
Now in your Controller you need 2 Actions现在在您的控制器中,您需要 2 个操作
GET
method to return the View GET
方法返回视图POST
method to POST back the form POST
返回表单的POST
方法
public ActionResult CreateCountry() { return PartialView(new CountryDTO()); }
Now in the POST method you will Pass the DTO, Let's assume you have a Country
table in your Database, you will have to create a New Country type Object and add to the Context现在在 POST 方法中,您将传递 DTO,假设您的数据库中有一个
Country
表,您必须创建一个新的 Country 类型对象并添加到上下文中
[HttpPost]
public ActionResult CreateCountry(CountryDTO model)
{
if (ModelState.IsValid)
{
// Model State is Valid
// here you will create Context
using (var dbContext = new DATBASE_CONTEXT())
{
var newCountry = new Country() // Country is a Model from Database
{
CountryName = model.CountryName,
CentralLat = model.CentralLat,
// Map All Properties from View Model to Model
};
// Add the New Country to the Countries
dbContext.Countries.Add(newCountry);
// Save Database Changes
dbContext.SaveChanges();
}
}
return PartialView(model);
}
IF you want to display this Country:如果要显示此国家/地区:
public ActionResult CountryDetails(int id)
{
var model = new CountryDTO();
using (var dbContext = new DATABASE_CONTEXT())
{
var country = dbContext.Country.First(s => s.CountryId == id);
model.CountryName = country.CountryName;
// Same for other Properties
// You can use AutoMapper Library to Map from Model to DTO/ViewModel
}
return View(model);
}
try
{
// <...>
return View(viewModel);
}
catch
{
return View(); //this is where the NullReferenceException is thrown
}
You get NullReferenceException
because your view expects the model and doesn't perform null checks in Razor.您得到
NullReferenceException
是因为您的视图需要模型并且不在 Razor 中执行空检查。
To verify this, you can create a dummy model and pass it into your return View(/* model */);
为了验证这一点,您可以创建一个虚拟模型并将其传递到您的
return View(/* model */);
call.称呼。
As I understood the exception trouble is not with DbContext but with lame model: "No key defined".据我了解,异常问题不是 DbContext 而是蹩脚模型:“未定义键”。 I think checking data-annotations might help.
我认为检查数据注释可能会有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.