我对MVC很新,我一直在尝试使用DTO作为模型类创建视图,但它似乎使用我用于模型的数据上下文类,即使我正在清除我在创建视图时的选择。
这个问题似乎导致了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.
我的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; }
}
}
控制器方法:
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
}
}
我意识到我可以通过检查空值来摆脱NullReferenceException,但我不知道如何解决我的DTO问题。
答案 0 :(得分:2)
我将尝试使用ViewModel / DTO来解释创建表单和POST。
ViewModel不在数据库上下文中,因此,如果您使用的是ViewModel,则必须将数据从ViewModel映射到Model和Model到ViewModel。
因此,如果您正在阅读数据库
如果您要写入数据库
假设你有一个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; }
}
创建一个控制器,即CountryController
,您有一个观看文件夹Country
,右键单击国家/地区文件夹Add
- > View
,将其命名为CreateCountry
,将模型选为CountryDTO
您无法在此处选择DataContext,因为DTO不是Context
的一部分这将使用DTO中的字段创建您的视图。
现在在你的控制器中你需要2个动作
GET
方法返回视图 POST
方法回复表单
public ActionResult CreateCountry()
{
return PartialView(new CountryDTO());
}
现在在POST方法中你将通过DTO,让我们假设你的数据库中有一个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);
}
如果您想显示此国家/地区:
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);
}
答案 1 :(得分:0)
try
{
// <...>
return View(viewModel);
}
catch
{
return View(); //this is where the NullReferenceException is thrown
}
您得到NullReferenceException
,因为您的视图需要该模型,并且不会在Razor中执行空检查。
要验证这一点,您可以创建虚拟模型并将其传递到return View(/* model */);
来电。
答案 2 :(得分:0)
据我所知,异常问题不在于DbContext,而在于lame模型:“没有键定义”。我认为检查数据注释可能会有所帮助。
答案 3 :(得分:-2)