簡體   English   中英

使用 DTO 查看 - ASP.NET MVC

[英]View using DTO - ASP.NET MVC

我對 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 問題。

我將嘗試解釋如何使用 ViewModel/DTO 創建一個表單並回傳。

ViewModel 位於數據庫上下文之外,因此如果您使用的是 ViewModel,則必須將數據從 ViewModel 映射到 Model,並將 Model 映射到 ViewModel。

所以如果你從數據庫中讀取

  1. 創建數據庫上下文
  2. 讀取你想讀取的數據
  3. 映射到 ViewModel
  4. 將 ViewModel 傳遞給 View 或 API

如果您正在寫入數據庫

  1. POST ViewMdoel 從視圖到控制器(你可以使用 Ajax)
  2. 創建數據庫上下文
  3. 從 ViewModel 到 Model 的映射
  4. 將模型保存到數據庫

假設你有一個 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並且您有一個 Views Folder Country ,右鍵單擊 Country Folder Add --> View ,將其命名為CreateCountry並選擇模型為CountryDTO

您不能在此處選擇 DataContext ,因為 DTO 不是 Context 的一部分

在此處輸入圖片說明

這將使用來自 DTO 的字段創建您的視圖。

現在在您的控制器中,您需要 2 個操作

  1. GET方法返回視圖
  2. POST返回表單的POST方法

    public ActionResult CreateCountry() { return PartialView(new CountryDTO()); }

現在在 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);
    }

在此處輸入圖片說明

如果要顯示此國家/地區:

    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
}

您得到NullReferenceException是因為您的視圖需要模型並且不在 Razor 中執行空檢查。

為了驗證這一點,您可以創建一個虛擬模型並將其傳遞到您的return View(/* model */); 稱呼。

據我了解,異常問題不是 DbContext 而是蹩腳模型:“未定義鍵”。 我認為檢查數據注釋可能會有所幫助。

我創建了一個新的視圖模型,其中包含我需要的兩個模型的所有內容。

然后我在控制器中設置視圖模型的值。

這給了我想要的結果。 在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM