2015-09-14 109 views
0

我是相当新的MVC和我一直在试图创建使用DTO作为模型类的视图,但它似乎是用我使用的数据上下文类我模型,即使我正在创建视图时清除选择。查看使用DTO - ASP.NET MVC

这个问题似乎是造成这是由以下异常被抛出并没有任何返回到它的视图造成一个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,但是我d我没有任何想法如何解决我的DTO问题。

+0

DTO是不是你的数据上下文,这就是为什么,你要办理的DTO /的ViewModels自己的上下文的一部分。 –

+0

@DawoodAwan我认为这可能是问题。我不确定如何去为DTO创建上下文类。我在我的当前上下文类中有“public partial class LocalModel:DbContext”,什么会替换“DbContext”? (对于我缺乏技术演讲感到抱歉)。 – TheHornyDonut

回答

-2

我创建了一个新的视图模型包含一切我需要从两个模型。

然后,我在控制器中设置视图模型的值。

这给了我我想要的结果。 enter image description here

0
try 
{ 
    // <...> 
    return View(viewModel); 
} 
catch 
{ 
    return View(); //this is where the NullReferenceException is thrown 
} 

你得到NullReferenceException因为你的观点预计,模型和剃须刀不执行空检查。

为了验证这一点,你可以创建一个虚拟模型,并把它传递到您的通话return View(/* model */);

+0

我了解的不多,真正的问题是关于DTO – TheHornyDonut

0

我的理解异常麻烦不与的DbContext但跛脚模式:“无定义的关键”。我认为检查数据注释可能会有所帮助。

+0

它不应该被使用的DbContext,作为DTO正在接受它从两个已经存在的模型的数据。 – TheHornyDonut

2

我将尝试使用一个ViewModel/DTO创建一个表单和POST回来解释。

的ViewModels是数据库环境之外,因此,如果您使用的是视图模型,你必须从地图视图模型的数据,模型和模型视图模型。

所以,如果你是从数据库中读取

  1. 创建的DbContext
  2. 读取数据要读
  3. 映射到一个视图模型
  4. 通行证视图模型到视图或API

如果您要写入数据库

  1. POST ViewMdoel从查看到控制器(可以使用Ajax)
  2. 创建的DbContext
  3. 从视图模型
  4. 地图到模型
  5. 保存模型数据库

假设你有一个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是不是上下文的一部分

enter image description here

这将创建您的视图与来自DTO的字段。

现在您的控制器需要2个操作

  1. GET方法返回查看
  2. 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); 
    } 

enter image description here

如果你想显示这个国家:

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); 
    } 
+0

我能够选择上下文,但我不想,但它仍然使用相同的语境像我的模特,甚至当我清除选择。 – TheHornyDonut

+0

你必须创建在控制器环境或你的数据层 - 使用(VAR的DbContext =新DATABASE_CONTEXT()) –

+0

我不明白为什么DTO需要是的DbContext的一部分,因为它存储的数据是不是来自数据库,它不是来自应用程序中的两个模型。 – TheHornyDonut