locked
How to reference to external dll for model? RRS feed

  • Question

  • User521171331 posted

    Hi,

    I have my two projects in my solution.

    • Web MVC (to consume the Web API)
    • Web API 

    My domain model is located in both project. I want to remove my model in Web MVC so that I can reference to Web API model. My current code in my add.cshtml is:

    @model Mvc.Models.Employee
    
    @{
        ViewBag.Title = "Add Form";
    }
    
    <div class="form-body">
        @using (Html.BeginForm())
        {
            @Html.HiddenFor(model => model.EmployeeID)
    
            <div class="form-group">
                @Html.LabelFor(model => model.Name)
                @Html.EditorFor(model => model.Name)
                @Html.ValidationMessageFor(model => model.Name)
            </div>
    ...
            <div class="form-group">
                <input type="submit" value="Submit" class="btn button" />
                <input type="reset" value="Reset" class="btn button" />
            </div>
        }
    </div>

    I have added the web api dll to make the changes (in blue) to but error hit at the line with red 

    @using WebApi.Models
    
    @{
        ViewBag.Title = "Add Form";
    }
    
    <div class="form-body">
        @using (Html.BeginForm())
        {
            @Html.HiddenFor(model => model.EmployeeID)
    
            <div class="form-group">
                @Html.LabelFor(model => model.Name)
                @Html.EditorFor(model => model.Name)
                @Html.ValidationMessageFor(model => model.Name)
            </div>
    ...
            <div class="form-group">
                <input type="submit" value="Submit" class="btn button" />
                <input type="reset" value="Reset" class="btn button" />
            </div>
        }
    </div>

     In my controller, I can change it (in blue) though with no error

    using System.Collections.Generic;
    using System.Net.Http;
    using System.Web.Mvc;
    using WebApi.Models;
    //using Mvc.Models;
    
    namespace Mvc.Controllers
    {
        public class EmployeeController : Controller
        {
            private readonly string controllerName = "Employees";
           
    [HttpPost]
            public ActionResult Add(Employee emp)
            {
                
                    HttpResponseMessage response = GlobalVariables.WebApiClient.PostAsJsonAsync(controllerName, emp).Result;
                    TempData["SuccessMessage"] = "Saved Successfully";
                
            }
        }
    }

    Monday, December 31, 2018 1:19 AM

Answers

  • User1120430333 posted

    My domain model is located in both project. I want to remove my model in Web MVC so that I can reference to Web API model. 

    A domain model should not be traveling between the MVC project and the WebAPI project IMO, which are two different processes. That's the job of a DTO.

    https://en.wikipedia.org/wiki/Data_transfer_object

    https://www.codeproject.com/Articles/1050468/Data-Transfer-Object-Design-Pattern-in-Csharp

    https://docs.microsoft.com/en-us/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-5

    Now you can have a 3rd project a classlib project called Entities or whatever you want to call it where the DTO(s) will be kept. You can then set project reference to Entities by both the MVC and WebAPI projects will know about the DTO(s).

    You should learn how to use a viewmodel for a view. You should also learn how to use a model object.

    https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/overview/understanding-models-views-and-controllers-cs

    <copied>

    An MVC model contains all of your application logic that is not contained in a view or a controller. The model should contain all of your application business logic, validation logic, and database access logic. For example, if you are using the Microsoft Entity Framework to access your database, then you would create your Entity Framework classes (your .edmx file) in the Models folder.

    A view should contain only logic related to generating the user interface. A controller should only contain the bare minimum of logic required to return the right view or redirect the user to another action (flow control). Everything else should be contained in the model.

    In general, you should strive for fat models and skinny controllers. Your controller methods should contain only a few lines of code. If a controller action gets too fat, then you should consider moving the logic out to a new class in the Models folder.

    <end>

    https://www.tutlane.com/tutorial/aspnet-mvc/how-to-use-viewmodel-in-asp-net-mvc-with-example

    Example code.....

    @using ProgMgmntCore2UserIdentity.Models
    @model ProjectViewModels.Project
    
    <!DOCTYPE html>
    
    <style type="text/css">
        .editor-field > label {
            float: left;
            width: 150px;
        }
        .txtbox {
            font-family: Arial, Helvetica, sans-serif;
            font-size: 12px;
            background: white;
            color: black;
            cursor: text;
            border-bottom: 1px solid #104A7B;
            border-right: 1px solid #104A7B;
            border-left: 1px solid #104A7B;
            border-top: 1px solid #104A7B;
            padding-top: 10px;
        }       
    </style>
    <html>
    <head>
        <title>Edit</title>
    </head>
    
    <body>
        <h1>Project</h1>
    
        @using (Html.BeginForm())
        {
    
            @Html.ValidationSummary(false, "", new { @class = "text-danger" })
    
        <fieldset>
    
            <legend>Edit</legend>
    
            @Html.HiddenFor(model => model.ProjectId)
    
            <div class="editor-field">
                @Html.Label("Project Name:")
                @Html.TextBoxFor(model => model.ProjectName, new { @Cssclass = "txtbox" })
                @Html.ValidationMessageFor(model => model.ProjectName)
            </div>
            <br />
            <div class="editor-field">
                @Html.Label("Client Name:")
                @Html.TextBoxFor(model => model.ClientName, new { @Cssclass = "txtbox" })
                @Html.ValidationMessageFor(model => model.ClientName)
            </div>
            <br />
            <div class="editor-field">
                @Html.Label("Technology:")
                @Html.TextBoxFor(model => model.Technology, new { @Cssclass = "txtbox" })
                @Html.ValidationMessageFor(model => model.Technology)
            </div>
            <br />
            <div class="editor-field">
                @Html.Label("Start Date:")
                @Html.TextBoxFor(model => model.StartDate, new { @Cssclass = "txtbox" })
                @Html.ValidationMessageFor(model => model.StartDate)
            </div>
            <br />
            <div class="editor-field">
                @Html.Label("End Date:")
                @Html.TextBoxFor(model => model.EndDate, new { @Cssclass = "txtbox" })
                @Html.ValidationMessageFor(model => model.EndDate)
            </div>
            <br />
            <div class="editor-field">
                @Html.Label("Cost:")
                @Html.TextBoxFor(model => model.Cost, new { @Cssclass = "txtbox" })
                @Html.ValidationMessageFor(model => model.Cost)
            </div>
            <br />
            <div class="editor-field">
                @Html.Label("Project Type:")
                @Html.DropDownListFor(model => model.ProjectType, Model.ProjectTypes)
            </div>
            <br />
            <p>
                <input type="submit" name="submit" value="Save" />
                <input type="submit" name="submit" value="Cancel" />
            </p>
    
        </fieldset>
        }
    
    </body>
    </html>
    
    
    
    
    
    
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Mvc.Rendering;
    
    namespace ProgMgmntCore2UserIdentity.Models
    {
        public class ProjectViewModels
        {
            public class Project
            {
                public int ProjectId { get; set; }
    
                [Required(ErrorMessage = "Client Name is required")]
                [StringLength(50)]
                public string ClientName { get; set; }
    
                [Required(ErrorMessage = "Project Name is required")]
                [StringLength(50)]
                public string ProjectName { get; set; }
    
                [Required(ErrorMessage = "Technology is required")]
                [StringLength(50)]
                public string Technology { get; set; }
    
                [Required(ErrorMessage = "Project Type is required")]
                public string ProjectType { get; set; }
    
                [Required(ErrorMessage = "Start Date is required")]
                [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM-dd-yyyy}")]
                public DateTime? StartDate { get; set; }
    
                [Required(ErrorMessage = "End Date is required")]
                [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM-dd-yyyy}")]
                public DateTime? EndDate { get; set; }
    
                [Required(ErrorMessage = "Cost is required")]
                public decimal? Cost { get; set; }
    
                public List<SelectListItem> ProjectTypes { get; set; }
            }
           
            public List<Project> Projects { get; set; }
            
        }
    }
    using System;
    using System.Linq;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.ModelBinding;
    using ProgMgmntCore2UserIdentity.Models;
    
    namespace ProgMgmntCore2UserIdentity.Controllers
    {
        public class ProjectController : Controller
        {
            private readonly IProjectModel _projectModel;
            private readonly IModelHelper _modelHelper;
           
            public ProjectController(IProjectModel projectModel,   IModelHelper modelHelper)
            {
                _projectModel = projectModel;
                _modelHelper = modelHelper;
            }
    
            // GET: Project
            [Authorize]
            public ActionResult Index()
            {
                return View(_projectModel.GetProjectsByUserId(User.Identity.Name));
            }
    
            [Authorize]
            public ActionResult Details(int id = 0)
            {
                return id == 0 ? null : View(_projectModel.Edit(id));
            }
    
            [Authorize]
            public ActionResult Create()
            {
                return View(_projectModel.Create());
            }
    
            [Authorize]
            [HttpPost]
            public ActionResult Create(ProjectViewModels.Project project, string submit)
            {
                if (submit == "Cancel") return RedirectToAction("Index");
    
                ValidateddlProjectTypes();
    
                project.ProjectType = (Request.Form["ddlProjectTypes"]);
    
                if (ModelState.IsValid && _modelHelper.IsEndDateLessThanStartDate(project, "Project"))
                    ModelState.AddModelError(string.Empty, "End Date cannot be less than Start Date.");
    
                if (!ModelState.IsValid) return View(_projectModel.PopulateSelectedList(project));
    
                _projectModel.Create(project, User.Identity.Name);
                return RedirectToAction("Index");
            }
    
            [Authorize]
            public ActionResult Edit(int id = 0)
            {
                return id == 0 ? null : View(_projectModel.Edit(id));
            }
    
            [Authorize]
            [HttpPost]
            public ActionResult Edit(ProjectViewModels.Project project, string submit)
            {
                if (submit == "Cancel") return RedirectToAction("Index");
    
                if (ModelState.IsValid && _modelHelper.IsEndDateLessThanStartDate(project, "Project"))
                    ModelState.AddModelError(String.Empty, "End Date cannot be less than Start Date.");
    
                if (!ModelState.IsValid) return View(_projectModel.PopulateSelectedList(project));
    
                var theproject = new ProjectViewModels.Project();
    
                theproject = project;
    
                theproject.ProjectType = Request.Form["ProjectType"];
    
                _projectModel.Edit(theproject, User.Identity.Name);
                return RedirectToAction("Index");
            }
    
            public ActionResult Delete(int id = 0)
            {
                if (id > 0) _projectModel.Delete(id);
    
                return RedirectToAction("Index");
            }
       
            public ActionResult Cancel()
            {
                return RedirectToAction("Index", "Home");
            }
    
            public ActionResult UploadFile(int id)
            {
                return RedirectToAction("Index", "Upload", new { id = id, type = "PM" });
            }
    
            private void ValidateddlProjectTypes()
            {
                if (Request.Form["ddlProjectTypes"] == string.Empty)
                  return;
           
                foreach (var key in ModelState.Keys.ToList().Where(key => ModelState.ContainsKey(key)))
                {
                    if (key != "ProjectType") continue;
                    ModelState[key].Errors.Clear();
                    ModelState[key].ValidationState = ModelValidationState.Valid;
                }
            }
        }
    }
    namespace ProgMgmntCore2UserIdentity.Models
    {
        public interface IProjectModel
        {
            ProjectViewModels GetProjectsByUserId(string userid);
            ProjectViewModels.Project GetProjectById(int id);
            ProjectViewModels.Project Create();
            void Create(ProjectViewModels.Project project, string userid);
            ProjectViewModels.Project Edit(int id);
            void Edit(ProjectViewModels.Project project, string userid);
            void Delete(int id);
            ProjectViewModels.Project PopulateSelectedList(ProjectViewModels.Project project);
        }
    }
    ==========================================================
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Entities;
    using Microsoft.AspNetCore.Mvc.Rendering;
    using Microsoft.Extensions.Caching.Memory;
    using ProgMgmntCore2UserIdentity.WebApi;
    
    namespace ProgMgmntCore2UserIdentity.Models
    {
        public class ProjectModel : IProjectModel
        {
            private readonly IMemoryCache _memoryCache;
            private readonly IWebApi _webApi;
    
            public ProjectModel(IWebApi webApi, IMemoryCache memoryCache)
            {
                _memoryCache = memoryCache;
                _webApi = webApi;
            }
    
            public ProjectViewModels GetProjectsByUserId(string userid)
            {
                var vm = new ProjectViewModels {Projects = new List<ProjectViewModels.Project>()};
    
                var dtos = _webApi.GetProjsByUserIdApi(userid).ToList();
                
                vm.Projects.AddRange(dtos.Select(dto => new ProjectViewModels.Project()
                {
                    ProjectId = dto.ProjectId,
                    ClientName = dto.ClientName,
                    ProjectName = dto.ProjectName,
                    Technology = dto.Technology,
                    ProjectType = dto.ProjectType,
                    StartDate = dto.StartDate,
                    EndDate = dto.EndDate,
                    Cost = dto.Cost
                }).ToList());
    
                return vm;
            }
    
            public ProjectViewModels.Project GetProjectById(int id)
            {
                var responseDto = _webApi.GetProjByIdApi(id);
    
                var project = new ProjectViewModels.Project
                {
                    ProjectId = responseDto.ProjectId,
                    ClientName = responseDto.ClientName,
                    ProjectName = responseDto.ProjectName,
                    Technology = responseDto.Technology,
                    ProjectType = responseDto.ProjectType,
                    StartDate = responseDto.StartDate,
                    EndDate = responseDto.EndDate,
                    Cost = responseDto.Cost
                };
    
                return project;
            }
    
            public ProjectViewModels.Project Create()
            {
                var project = new ProjectViewModels.Project();
                return PopulateSelectedList(project);
            }
    
            public void Create(ProjectViewModels.Project project, string userid)
            {
                var dto = new DtoProject
                {
                    ProjectId = project.ProjectId,
                    ClientName = project.ClientName,
                    ProjectName = project.ProjectName,
                    ProjectType = project.ProjectType,  
                    Technology = project.Technology,
                    UserId = userid,
                    StartDate = (DateTime) project.StartDate,
                    EndDate = (DateTime) project.EndDate,
                    Cost = (decimal) project.Cost
                };
    
                _webApi.CreateProjectApi(dto);
            }
    
            public ProjectViewModels.Project Edit(int id)
            {
                var responseDto = _webApi.GetProjByIdApi(id);
    
                var project = new ProjectViewModels.Project
                {
                    ProjectId = responseDto.ProjectId,
                    ClientName = responseDto.ClientName,
                    ProjectName = responseDto.ProjectName,
                    Technology = responseDto.Technology,
                    ProjectType = responseDto.ProjectType,
                    StartDate = responseDto.StartDate,
                    EndDate = responseDto.EndDate,
                    Cost = responseDto.Cost
                };
    
                project = PopulateSelectedList(project);
    
                return project;
            }
    
            public void Edit(ProjectViewModels.Project project, string userid)
            {
                var dto = new DtoProject
                {
                    ProjectId = project.ProjectId,
                    ClientName = project.ClientName,
                    ProjectName = project.ProjectName,
                    ProjectType = project.ProjectType,
                    Technology = project.Technology,
                    UserId = userid,
                    StartDate = (DateTime) project.StartDate,
                    EndDate = (DateTime) project.EndDate,
                    Cost = (decimal) project.Cost
                };
    
                _webApi.UpdateProjectApi(dto); 
            }
    
            public void Delete(int id)
            {
                _webApi.DeleteProjectApi(new DtoId{Id = id});
            }
    
            public ProjectViewModels.Project PopulateSelectedList(ProjectViewModels.Project project)
            {
                bool isExist = _memoryCache.TryGetValue("DtoCache", out DtoCache dtocache);
    
                if (!isExist)
                {
                    dtocache = _webApi.GetCacheApi();
              
                    var cacheEntryOptions = new MemoryCacheEntryOptions()
                        .SetSlidingExpiration(TimeSpan.FromSeconds(30));
                    
                    _memoryCache.Set("DtoCache", dtocache, cacheEntryOptions);
                }
    
                project.ProjectTypes = new List<SelectListItem>();
    
                foreach (var pt in dtocache.ProjectTypes)
                {
                    var sli = new SelectListItem {Value = pt.Value, Text = pt.Text};
                    project.ProjectTypes.Add(sli);
                }
           
                var selected = (from a in project.ProjectTypes.Where(a => a.Value == project.ProjectType) select a)
                    .SingleOrDefault();
    
                if (selected != null)
                    selected.Selected = true;
    
                return project;
            }
        }
    }
    
    
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using Entities;
    
    namespace ProgMgmntCore2UserIdentity.WebApi
    {
        public interface IWebApi
        {
            List<DtoProject> GetProjsByUserIdApi(string userid);
            DtoProject GetProjByIdApi(int id);
            void CreateProjectApi(DtoProject dto);
            void UpdateProjectApi(DtoProject dto);
            void DeleteProjectApi(DtoId dto);
        }
    }

    using System;
    using System.Collections.Generic;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using System.Text;
    using Entities;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    
    namespace ProgMgmntCore2UserIdentity.WebApi
    {
        public class WebApi : IWebApi
        {
            #region ProjectApi
            
            public List<DtoProject> GetProjsByUserIdApi(string userid)
            {
                var dtoprojects = new List<DtoProject>();
    
                using (var client = new HttpClient())
                {
                    var uri = new Uri("http://progmgmntcore2api.com/api/project/GetProjsByUserId?userid=" + userid);
    
                    var response = client.GetAsync(uri).Result;
    
                    if (!response.IsSuccessStatusCode)
                        throw new Exception(response.ToString());
    
                    var responseContent = response.Content;
                    var responseString = responseContent.ReadAsStringAsync().Result;
    
                    dynamic projects = JArray.Parse(responseString) as JArray;
    
                    foreach (var obj in projects)
                    {
                        DtoProject dto = obj.ToObject<DtoProject>();
    
                        dtoprojects.Add(dto);
                    }
                }
    
                return dtoprojects;
            }
    
            public DtoProject GetProjByIdApi(int id)
            {
                DtoProject dto;
    
                using (var client = new HttpClient())
                {
                    var uri = new Uri("http://progmgmntcore2api.com/api/project/GetProjById?id=" + id);
                    HttpResponseMessage getResponseMessage = client.GetAsync(uri).Result;
    
                    if (!getResponseMessage.IsSuccessStatusCode)
                        throw new Exception(getResponseMessage.ToString());
    
                    var responsemessage = getResponseMessage.Content.ReadAsStringAsync().Result;
    
                    dynamic project = JsonConvert.DeserializeObject(responsemessage);
    
                    dto = project.ToObject<DtoProject>();
                }
    
                return dto;
            }
    
            public void CreateProjectApi(DtoProject dto)
            {
                using (var client = new HttpClient { BaseAddress = new Uri("http://progmgmntcore2api.com") })
                {
                    string serailizeddto = JsonConvert.SerializeObject(dto);
    
                    var inputMessage = new HttpRequestMessage
                    {
                        Content = new StringContent(serailizeddto, Encoding.UTF8, "application/json")
                    };
    
                    inputMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    
                    HttpResponseMessage message =
                        client.PostAsync("api/project/CreateProject", inputMessage.Content).Result;
    
                    if (!message.IsSuccessStatusCode)
                        throw new Exception(message.ToString());
                }
            }
    
            public void UpdateProjectApi(DtoProject dto)
            {
                using (var client = new HttpClient { BaseAddress = new Uri("http://progmgmntcore2api.com") })
                {
                    string serailizeddto = JsonConvert.SerializeObject(dto);
    
                    var inputMessage = new HttpRequestMessage
                    {
                        Content = new StringContent(serailizeddto, Encoding.UTF8, "application/json")
                    };
    
                    inputMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    
                    HttpResponseMessage message =
                        client.PostAsync("api/project/UpdateProject", inputMessage.Content).Result;
    
                    if (!message.IsSuccessStatusCode)
                        throw new Exception(message.ToString());
                }
            }
    
            public void DeleteProjectApi(DtoId dto)
            {
                using (var client = new HttpClient { BaseAddress = new Uri("http://progmgmntcore2api.com") })
                {
                    string serailizeddto = JsonConvert.SerializeObject(dto);
    
                    var inputMessage = new HttpRequestMessage
                    {
                        Content = new StringContent(serailizeddto, Encoding.UTF8, "application/json")
                    };
    
                    inputMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    
                    HttpResponseMessage message =
                        client.PostAsync("api/project/DeleteProject", inputMessage.Content).Result;
    
                    if (!message.IsSuccessStatusCode)
                        throw new Exception(message.ToString());
                }
            }
    using System.Collections.Generic;
    using DAL;
    using Entities;
    using Microsoft.AspNetCore.Mvc;
    
    namespace ProgMgmntCore2Api.Controllers
    {
        [Produces("application/json")]
        [Route("api/[controller]")]
        [ApiController]
    
        public class ProjectController : ControllerBase, IProjectController
        {
            private readonly IDaoProject _daoProject;
    
            public ProjectController(IDaoProject daoProject)
            {
                _daoProject = daoProject;
            }
    
            [HttpGet]
            [Route("GetProjById")]
            public DtoProject GetProjectById(int id)
            {
                return  _daoProject.GetProjectById(id);
            }
            
            [HttpGet]
            [Route("GetProjsByUserId")]
            public List<DtoProject> GetProjectsByUserId(string userid)
            {
                return _daoProject.GetProjectsByUserId(userid);
            }
    
            [HttpPost]
            [Route("CreateProject")]
            public void Post_CreateProject(DtoProject dto)
            {
                _daoProject.CreateProject(dto);
            }
    
            [HttpPost]
            [Route("DeleteProject")]
            public void Post_DeleteProject(DtoId dto)
            {
                _daoProject.DeleteProject(dto.Id);
            }
    
            [HttpPost]
            [Route("UpdateProject")]
            public void Post_UpdateProject(DtoProject dto)
            {
                _daoProject.UpdateProject(dto);
            }
        }
    }
    
    using System;
    using System.Collections.Generic;
    using System.Text;
    using Entities;
    
    namespace DAL
    {
        public interface IDaoProject
        {
            DtoProject GetProjectById(int id);
            List<DtoProject> GetProjectsByUserId(string userid);
            void CreateProject(DtoProject dto);
            void UpdateProject(DtoProject dto);
            void DeleteProject(int id);
        }
    }
    
    ========================================
    
    using System.Collections.Generic;
    using System.Linq;
    using System.Transactions;
    using DAL.Models.DB;
    using Entities;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.Extensions.Options;
    
    namespace DAL
    {
        public class DaoProject :IDaoProject
        {
            private readonly IOptions<ConnectionStrings> _options;
            
            public DaoProject(IOptions<ConnectionStrings> options)
            {
                _options = options;
            }
    
            public DtoProject GetProjectById(int id)
            {
                var dto = new DtoProject();
    
                using (var context = new ProjectManagementContext(_options))
                {
                    var project = (context.Projects.Where(a => a.ProjectId == id)).SingleOrDefault();
    
                    if (project == null) return dto;
                    dto.ProjectId = project.ProjectId;
                    dto.ClientName = project.ClientName;
                    dto.ProjectName = project.ProjectName;
                    dto.Technology = project.Technology;
                    dto.ProjectType = project.ProjectType;
                    dto.UserId = project.UserId;
                    dto.StartDate = project.StartDate;
                    dto.EndDate = project.EndDate;
                    dto.Cost = project.Cost;
                }
    
                return dto;
            }
    
            public List<DtoProject> GetProjectsByUserId(string userid)
            {
                var dtos = new List<DtoProject>();
    
                using (var context = new ProjectManagementContext(_options))
                {
                    
                    dtos = (from a in context.Projects.Where(a => a.UserId.Contains(userid))
                        select new DtoProject
                        {
                            ProjectId = a.ProjectId,
                            ClientName = a.ClientName,
                            ProjectName = a.ProjectName,
                            Technology = a.Technology,
                            ProjectType = a.ProjectType,
                            UserId = a.UserId,
                            StartDate = a.StartDate,
                            EndDate = a.EndDate,
                            Cost = a.Cost
                        }).ToList();
                }
    
                return dtos;
            }
    
            public void CreateProject(DtoProject dto)
            {
                using (var context = new ProjectManagementContext(_options))
                {
                    var project = new Projects
                    {
                        ClientName = dto.ClientName,
                        ProjectName = dto.ProjectName,
                        Technology = dto.Technology,
                        ProjectType = dto.ProjectType,
                        UserId = dto.UserId,
                        StartDate = dto.StartDate,
                        EndDate = dto.EndDate,
                        Cost = dto.Cost
                    };
    
                    context.Projects.Add(project);
                    context.SaveChanges();
               }
            }
    
            public void UpdateProject(DtoProject dto)
            {
                var project = new Projects();
                
                using (var context = new ProjectManagementContext(_options))
                {
                   project = (context.Projects.Where(a => a.ProjectId == dto.ProjectId)).SingleOrDefault();
                }
    
                if (project != null)
                {
                    project.ClientName = dto.ClientName;
                    project.ProjectName = dto.ProjectName;
                    project.Technology = dto.Technology;
                    project.ProjectType = dto.ProjectType;
                    project.UserId = dto.UserId;
                    project.StartDate = dto.StartDate;
                    project.EndDate = dto.EndDate;
                    project.Cost = dto.Cost;
                }
    
                using (var dbcontext = new ProjectManagementContext(_options))
                {
                    if (project == null) return;
                    dbcontext.Entry(project).State = EntityState.Modified;
                    dbcontext.SaveChanges();
                }
            }
    
            public void DeleteProject(int id)
            {
                Projects project;
    
                using (var context = new ProjectManagementContext(_options))
                {
                   project = (context.Projects.Where(a => a.ProjectId == id)).SingleOrDefault();
                }
    
                if (project == null) return;
    
                using (var newContext = new ProjectManagementContext(_options))
                {
                   
                    var tasks = new DaoTask(_options).GetTasksByProjectId(project.ProjectId);
                    using (TransactionScope scope = new TransactionScope())
                    {
                        foreach (var task in tasks)
                        {
                            new DaoTask(_options).DeleteTask(task.TaskId);
                        }
    
                        newContext.Entry(project).State = EntityState.Deleted;
                        newContext.SaveChanges();
    
                        scope.Complete();
                    }
                }
            }
        }
    }
    
    
    using System;
    
    namespace Entities
    {
        public class DtoProject
        {
            public int ProjectId { get; set; }
            public string ClientName { get; set; }
            public string ProjectName { get; set; }
            public string Technology { get; set; }
            public string ProjectType { get; set; }
            public string UserId { get; set; }
            public DateTime StartDate { get; set; }
            public DateTime EndDate { get; set; }
            public decimal Cost { get; set; }
        }
    }

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, December 31, 2018 7:07 AM
  • User1120430333 posted

    I need to have ViewModel in both projects

    Just simply receive the object in your API in the back-end, something like

    Again, the viewmodel's job is to work with a view in MVC. The VM is not to be traveling anywhere. The DTO's job is to hold data and travel between layers, tiers or processes.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, December 31, 2018 4:51 PM

All replies

  • User1120430333 posted

    My domain model is located in both project. I want to remove my model in Web MVC so that I can reference to Web API model. 

    A domain model should not be traveling between the MVC project and the WebAPI project IMO, which are two different processes. That's the job of a DTO.

    https://en.wikipedia.org/wiki/Data_transfer_object

    https://www.codeproject.com/Articles/1050468/Data-Transfer-Object-Design-Pattern-in-Csharp

    https://docs.microsoft.com/en-us/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-5

    Now you can have a 3rd project a classlib project called Entities or whatever you want to call it where the DTO(s) will be kept. You can then set project reference to Entities by both the MVC and WebAPI projects will know about the DTO(s).

    You should learn how to use a viewmodel for a view. You should also learn how to use a model object.

    https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/overview/understanding-models-views-and-controllers-cs

    <copied>

    An MVC model contains all of your application logic that is not contained in a view or a controller. The model should contain all of your application business logic, validation logic, and database access logic. For example, if you are using the Microsoft Entity Framework to access your database, then you would create your Entity Framework classes (your .edmx file) in the Models folder.

    A view should contain only logic related to generating the user interface. A controller should only contain the bare minimum of logic required to return the right view or redirect the user to another action (flow control). Everything else should be contained in the model.

    In general, you should strive for fat models and skinny controllers. Your controller methods should contain only a few lines of code. If a controller action gets too fat, then you should consider moving the logic out to a new class in the Models folder.

    <end>

    https://www.tutlane.com/tutorial/aspnet-mvc/how-to-use-viewmodel-in-asp-net-mvc-with-example

    Example code.....

    @using ProgMgmntCore2UserIdentity.Models
    @model ProjectViewModels.Project
    
    <!DOCTYPE html>
    
    <style type="text/css">
        .editor-field > label {
            float: left;
            width: 150px;
        }
        .txtbox {
            font-family: Arial, Helvetica, sans-serif;
            font-size: 12px;
            background: white;
            color: black;
            cursor: text;
            border-bottom: 1px solid #104A7B;
            border-right: 1px solid #104A7B;
            border-left: 1px solid #104A7B;
            border-top: 1px solid #104A7B;
            padding-top: 10px;
        }       
    </style>
    <html>
    <head>
        <title>Edit</title>
    </head>
    
    <body>
        <h1>Project</h1>
    
        @using (Html.BeginForm())
        {
    
            @Html.ValidationSummary(false, "", new { @class = "text-danger" })
    
        <fieldset>
    
            <legend>Edit</legend>
    
            @Html.HiddenFor(model => model.ProjectId)
    
            <div class="editor-field">
                @Html.Label("Project Name:")
                @Html.TextBoxFor(model => model.ProjectName, new { @Cssclass = "txtbox" })
                @Html.ValidationMessageFor(model => model.ProjectName)
            </div>
            <br />
            <div class="editor-field">
                @Html.Label("Client Name:")
                @Html.TextBoxFor(model => model.ClientName, new { @Cssclass = "txtbox" })
                @Html.ValidationMessageFor(model => model.ClientName)
            </div>
            <br />
            <div class="editor-field">
                @Html.Label("Technology:")
                @Html.TextBoxFor(model => model.Technology, new { @Cssclass = "txtbox" })
                @Html.ValidationMessageFor(model => model.Technology)
            </div>
            <br />
            <div class="editor-field">
                @Html.Label("Start Date:")
                @Html.TextBoxFor(model => model.StartDate, new { @Cssclass = "txtbox" })
                @Html.ValidationMessageFor(model => model.StartDate)
            </div>
            <br />
            <div class="editor-field">
                @Html.Label("End Date:")
                @Html.TextBoxFor(model => model.EndDate, new { @Cssclass = "txtbox" })
                @Html.ValidationMessageFor(model => model.EndDate)
            </div>
            <br />
            <div class="editor-field">
                @Html.Label("Cost:")
                @Html.TextBoxFor(model => model.Cost, new { @Cssclass = "txtbox" })
                @Html.ValidationMessageFor(model => model.Cost)
            </div>
            <br />
            <div class="editor-field">
                @Html.Label("Project Type:")
                @Html.DropDownListFor(model => model.ProjectType, Model.ProjectTypes)
            </div>
            <br />
            <p>
                <input type="submit" name="submit" value="Save" />
                <input type="submit" name="submit" value="Cancel" />
            </p>
    
        </fieldset>
        }
    
    </body>
    </html>
    
    
    
    
    
    
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Mvc.Rendering;
    
    namespace ProgMgmntCore2UserIdentity.Models
    {
        public class ProjectViewModels
        {
            public class Project
            {
                public int ProjectId { get; set; }
    
                [Required(ErrorMessage = "Client Name is required")]
                [StringLength(50)]
                public string ClientName { get; set; }
    
                [Required(ErrorMessage = "Project Name is required")]
                [StringLength(50)]
                public string ProjectName { get; set; }
    
                [Required(ErrorMessage = "Technology is required")]
                [StringLength(50)]
                public string Technology { get; set; }
    
                [Required(ErrorMessage = "Project Type is required")]
                public string ProjectType { get; set; }
    
                [Required(ErrorMessage = "Start Date is required")]
                [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM-dd-yyyy}")]
                public DateTime? StartDate { get; set; }
    
                [Required(ErrorMessage = "End Date is required")]
                [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM-dd-yyyy}")]
                public DateTime? EndDate { get; set; }
    
                [Required(ErrorMessage = "Cost is required")]
                public decimal? Cost { get; set; }
    
                public List<SelectListItem> ProjectTypes { get; set; }
            }
           
            public List<Project> Projects { get; set; }
            
        }
    }
    using System;
    using System.Linq;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.ModelBinding;
    using ProgMgmntCore2UserIdentity.Models;
    
    namespace ProgMgmntCore2UserIdentity.Controllers
    {
        public class ProjectController : Controller
        {
            private readonly IProjectModel _projectModel;
            private readonly IModelHelper _modelHelper;
           
            public ProjectController(IProjectModel projectModel,   IModelHelper modelHelper)
            {
                _projectModel = projectModel;
                _modelHelper = modelHelper;
            }
    
            // GET: Project
            [Authorize]
            public ActionResult Index()
            {
                return View(_projectModel.GetProjectsByUserId(User.Identity.Name));
            }
    
            [Authorize]
            public ActionResult Details(int id = 0)
            {
                return id == 0 ? null : View(_projectModel.Edit(id));
            }
    
            [Authorize]
            public ActionResult Create()
            {
                return View(_projectModel.Create());
            }
    
            [Authorize]
            [HttpPost]
            public ActionResult Create(ProjectViewModels.Project project, string submit)
            {
                if (submit == "Cancel") return RedirectToAction("Index");
    
                ValidateddlProjectTypes();
    
                project.ProjectType = (Request.Form["ddlProjectTypes"]);
    
                if (ModelState.IsValid && _modelHelper.IsEndDateLessThanStartDate(project, "Project"))
                    ModelState.AddModelError(string.Empty, "End Date cannot be less than Start Date.");
    
                if (!ModelState.IsValid) return View(_projectModel.PopulateSelectedList(project));
    
                _projectModel.Create(project, User.Identity.Name);
                return RedirectToAction("Index");
            }
    
            [Authorize]
            public ActionResult Edit(int id = 0)
            {
                return id == 0 ? null : View(_projectModel.Edit(id));
            }
    
            [Authorize]
            [HttpPost]
            public ActionResult Edit(ProjectViewModels.Project project, string submit)
            {
                if (submit == "Cancel") return RedirectToAction("Index");
    
                if (ModelState.IsValid && _modelHelper.IsEndDateLessThanStartDate(project, "Project"))
                    ModelState.AddModelError(String.Empty, "End Date cannot be less than Start Date.");
    
                if (!ModelState.IsValid) return View(_projectModel.PopulateSelectedList(project));
    
                var theproject = new ProjectViewModels.Project();
    
                theproject = project;
    
                theproject.ProjectType = Request.Form["ProjectType"];
    
                _projectModel.Edit(theproject, User.Identity.Name);
                return RedirectToAction("Index");
            }
    
            public ActionResult Delete(int id = 0)
            {
                if (id > 0) _projectModel.Delete(id);
    
                return RedirectToAction("Index");
            }
       
            public ActionResult Cancel()
            {
                return RedirectToAction("Index", "Home");
            }
    
            public ActionResult UploadFile(int id)
            {
                return RedirectToAction("Index", "Upload", new { id = id, type = "PM" });
            }
    
            private void ValidateddlProjectTypes()
            {
                if (Request.Form["ddlProjectTypes"] == string.Empty)
                  return;
           
                foreach (var key in ModelState.Keys.ToList().Where(key => ModelState.ContainsKey(key)))
                {
                    if (key != "ProjectType") continue;
                    ModelState[key].Errors.Clear();
                    ModelState[key].ValidationState = ModelValidationState.Valid;
                }
            }
        }
    }
    namespace ProgMgmntCore2UserIdentity.Models
    {
        public interface IProjectModel
        {
            ProjectViewModels GetProjectsByUserId(string userid);
            ProjectViewModels.Project GetProjectById(int id);
            ProjectViewModels.Project Create();
            void Create(ProjectViewModels.Project project, string userid);
            ProjectViewModels.Project Edit(int id);
            void Edit(ProjectViewModels.Project project, string userid);
            void Delete(int id);
            ProjectViewModels.Project PopulateSelectedList(ProjectViewModels.Project project);
        }
    }
    ==========================================================
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Entities;
    using Microsoft.AspNetCore.Mvc.Rendering;
    using Microsoft.Extensions.Caching.Memory;
    using ProgMgmntCore2UserIdentity.WebApi;
    
    namespace ProgMgmntCore2UserIdentity.Models
    {
        public class ProjectModel : IProjectModel
        {
            private readonly IMemoryCache _memoryCache;
            private readonly IWebApi _webApi;
    
            public ProjectModel(IWebApi webApi, IMemoryCache memoryCache)
            {
                _memoryCache = memoryCache;
                _webApi = webApi;
            }
    
            public ProjectViewModels GetProjectsByUserId(string userid)
            {
                var vm = new ProjectViewModels {Projects = new List<ProjectViewModels.Project>()};
    
                var dtos = _webApi.GetProjsByUserIdApi(userid).ToList();
                
                vm.Projects.AddRange(dtos.Select(dto => new ProjectViewModels.Project()
                {
                    ProjectId = dto.ProjectId,
                    ClientName = dto.ClientName,
                    ProjectName = dto.ProjectName,
                    Technology = dto.Technology,
                    ProjectType = dto.ProjectType,
                    StartDate = dto.StartDate,
                    EndDate = dto.EndDate,
                    Cost = dto.Cost
                }).ToList());
    
                return vm;
            }
    
            public ProjectViewModels.Project GetProjectById(int id)
            {
                var responseDto = _webApi.GetProjByIdApi(id);
    
                var project = new ProjectViewModels.Project
                {
                    ProjectId = responseDto.ProjectId,
                    ClientName = responseDto.ClientName,
                    ProjectName = responseDto.ProjectName,
                    Technology = responseDto.Technology,
                    ProjectType = responseDto.ProjectType,
                    StartDate = responseDto.StartDate,
                    EndDate = responseDto.EndDate,
                    Cost = responseDto.Cost
                };
    
                return project;
            }
    
            public ProjectViewModels.Project Create()
            {
                var project = new ProjectViewModels.Project();
                return PopulateSelectedList(project);
            }
    
            public void Create(ProjectViewModels.Project project, string userid)
            {
                var dto = new DtoProject
                {
                    ProjectId = project.ProjectId,
                    ClientName = project.ClientName,
                    ProjectName = project.ProjectName,
                    ProjectType = project.ProjectType,  
                    Technology = project.Technology,
                    UserId = userid,
                    StartDate = (DateTime) project.StartDate,
                    EndDate = (DateTime) project.EndDate,
                    Cost = (decimal) project.Cost
                };
    
                _webApi.CreateProjectApi(dto);
            }
    
            public ProjectViewModels.Project Edit(int id)
            {
                var responseDto = _webApi.GetProjByIdApi(id);
    
                var project = new ProjectViewModels.Project
                {
                    ProjectId = responseDto.ProjectId,
                    ClientName = responseDto.ClientName,
                    ProjectName = responseDto.ProjectName,
                    Technology = responseDto.Technology,
                    ProjectType = responseDto.ProjectType,
                    StartDate = responseDto.StartDate,
                    EndDate = responseDto.EndDate,
                    Cost = responseDto.Cost
                };
    
                project = PopulateSelectedList(project);
    
                return project;
            }
    
            public void Edit(ProjectViewModels.Project project, string userid)
            {
                var dto = new DtoProject
                {
                    ProjectId = project.ProjectId,
                    ClientName = project.ClientName,
                    ProjectName = project.ProjectName,
                    ProjectType = project.ProjectType,
                    Technology = project.Technology,
                    UserId = userid,
                    StartDate = (DateTime) project.StartDate,
                    EndDate = (DateTime) project.EndDate,
                    Cost = (decimal) project.Cost
                };
    
                _webApi.UpdateProjectApi(dto); 
            }
    
            public void Delete(int id)
            {
                _webApi.DeleteProjectApi(new DtoId{Id = id});
            }
    
            public ProjectViewModels.Project PopulateSelectedList(ProjectViewModels.Project project)
            {
                bool isExist = _memoryCache.TryGetValue("DtoCache", out DtoCache dtocache);
    
                if (!isExist)
                {
                    dtocache = _webApi.GetCacheApi();
              
                    var cacheEntryOptions = new MemoryCacheEntryOptions()
                        .SetSlidingExpiration(TimeSpan.FromSeconds(30));
                    
                    _memoryCache.Set("DtoCache", dtocache, cacheEntryOptions);
                }
    
                project.ProjectTypes = new List<SelectListItem>();
    
                foreach (var pt in dtocache.ProjectTypes)
                {
                    var sli = new SelectListItem {Value = pt.Value, Text = pt.Text};
                    project.ProjectTypes.Add(sli);
                }
           
                var selected = (from a in project.ProjectTypes.Where(a => a.Value == project.ProjectType) select a)
                    .SingleOrDefault();
    
                if (selected != null)
                    selected.Selected = true;
    
                return project;
            }
        }
    }
    
    
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using Entities;
    
    namespace ProgMgmntCore2UserIdentity.WebApi
    {
        public interface IWebApi
        {
            List<DtoProject> GetProjsByUserIdApi(string userid);
            DtoProject GetProjByIdApi(int id);
            void CreateProjectApi(DtoProject dto);
            void UpdateProjectApi(DtoProject dto);
            void DeleteProjectApi(DtoId dto);
        }
    }

    using System;
    using System.Collections.Generic;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using System.Text;
    using Entities;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    
    namespace ProgMgmntCore2UserIdentity.WebApi
    {
        public class WebApi : IWebApi
        {
            #region ProjectApi
            
            public List<DtoProject> GetProjsByUserIdApi(string userid)
            {
                var dtoprojects = new List<DtoProject>();
    
                using (var client = new HttpClient())
                {
                    var uri = new Uri("http://progmgmntcore2api.com/api/project/GetProjsByUserId?userid=" + userid);
    
                    var response = client.GetAsync(uri).Result;
    
                    if (!response.IsSuccessStatusCode)
                        throw new Exception(response.ToString());
    
                    var responseContent = response.Content;
                    var responseString = responseContent.ReadAsStringAsync().Result;
    
                    dynamic projects = JArray.Parse(responseString) as JArray;
    
                    foreach (var obj in projects)
                    {
                        DtoProject dto = obj.ToObject<DtoProject>();
    
                        dtoprojects.Add(dto);
                    }
                }
    
                return dtoprojects;
            }
    
            public DtoProject GetProjByIdApi(int id)
            {
                DtoProject dto;
    
                using (var client = new HttpClient())
                {
                    var uri = new Uri("http://progmgmntcore2api.com/api/project/GetProjById?id=" + id);
                    HttpResponseMessage getResponseMessage = client.GetAsync(uri).Result;
    
                    if (!getResponseMessage.IsSuccessStatusCode)
                        throw new Exception(getResponseMessage.ToString());
    
                    var responsemessage = getResponseMessage.Content.ReadAsStringAsync().Result;
    
                    dynamic project = JsonConvert.DeserializeObject(responsemessage);
    
                    dto = project.ToObject<DtoProject>();
                }
    
                return dto;
            }
    
            public void CreateProjectApi(DtoProject dto)
            {
                using (var client = new HttpClient { BaseAddress = new Uri("http://progmgmntcore2api.com") })
                {
                    string serailizeddto = JsonConvert.SerializeObject(dto);
    
                    var inputMessage = new HttpRequestMessage
                    {
                        Content = new StringContent(serailizeddto, Encoding.UTF8, "application/json")
                    };
    
                    inputMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    
                    HttpResponseMessage message =
                        client.PostAsync("api/project/CreateProject", inputMessage.Content).Result;
    
                    if (!message.IsSuccessStatusCode)
                        throw new Exception(message.ToString());
                }
            }
    
            public void UpdateProjectApi(DtoProject dto)
            {
                using (var client = new HttpClient { BaseAddress = new Uri("http://progmgmntcore2api.com") })
                {
                    string serailizeddto = JsonConvert.SerializeObject(dto);
    
                    var inputMessage = new HttpRequestMessage
                    {
                        Content = new StringContent(serailizeddto, Encoding.UTF8, "application/json")
                    };
    
                    inputMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    
                    HttpResponseMessage message =
                        client.PostAsync("api/project/UpdateProject", inputMessage.Content).Result;
    
                    if (!message.IsSuccessStatusCode)
                        throw new Exception(message.ToString());
                }
            }
    
            public void DeleteProjectApi(DtoId dto)
            {
                using (var client = new HttpClient { BaseAddress = new Uri("http://progmgmntcore2api.com") })
                {
                    string serailizeddto = JsonConvert.SerializeObject(dto);
    
                    var inputMessage = new HttpRequestMessage
                    {
                        Content = new StringContent(serailizeddto, Encoding.UTF8, "application/json")
                    };
    
                    inputMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    
                    HttpResponseMessage message =
                        client.PostAsync("api/project/DeleteProject", inputMessage.Content).Result;
    
                    if (!message.IsSuccessStatusCode)
                        throw new Exception(message.ToString());
                }
            }
    using System.Collections.Generic;
    using DAL;
    using Entities;
    using Microsoft.AspNetCore.Mvc;
    
    namespace ProgMgmntCore2Api.Controllers
    {
        [Produces("application/json")]
        [Route("api/[controller]")]
        [ApiController]
    
        public class ProjectController : ControllerBase, IProjectController
        {
            private readonly IDaoProject _daoProject;
    
            public ProjectController(IDaoProject daoProject)
            {
                _daoProject = daoProject;
            }
    
            [HttpGet]
            [Route("GetProjById")]
            public DtoProject GetProjectById(int id)
            {
                return  _daoProject.GetProjectById(id);
            }
            
            [HttpGet]
            [Route("GetProjsByUserId")]
            public List<DtoProject> GetProjectsByUserId(string userid)
            {
                return _daoProject.GetProjectsByUserId(userid);
            }
    
            [HttpPost]
            [Route("CreateProject")]
            public void Post_CreateProject(DtoProject dto)
            {
                _daoProject.CreateProject(dto);
            }
    
            [HttpPost]
            [Route("DeleteProject")]
            public void Post_DeleteProject(DtoId dto)
            {
                _daoProject.DeleteProject(dto.Id);
            }
    
            [HttpPost]
            [Route("UpdateProject")]
            public void Post_UpdateProject(DtoProject dto)
            {
                _daoProject.UpdateProject(dto);
            }
        }
    }
    
    using System;
    using System.Collections.Generic;
    using System.Text;
    using Entities;
    
    namespace DAL
    {
        public interface IDaoProject
        {
            DtoProject GetProjectById(int id);
            List<DtoProject> GetProjectsByUserId(string userid);
            void CreateProject(DtoProject dto);
            void UpdateProject(DtoProject dto);
            void DeleteProject(int id);
        }
    }
    
    ========================================
    
    using System.Collections.Generic;
    using System.Linq;
    using System.Transactions;
    using DAL.Models.DB;
    using Entities;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.Extensions.Options;
    
    namespace DAL
    {
        public class DaoProject :IDaoProject
        {
            private readonly IOptions<ConnectionStrings> _options;
            
            public DaoProject(IOptions<ConnectionStrings> options)
            {
                _options = options;
            }
    
            public DtoProject GetProjectById(int id)
            {
                var dto = new DtoProject();
    
                using (var context = new ProjectManagementContext(_options))
                {
                    var project = (context.Projects.Where(a => a.ProjectId == id)).SingleOrDefault();
    
                    if (project == null) return dto;
                    dto.ProjectId = project.ProjectId;
                    dto.ClientName = project.ClientName;
                    dto.ProjectName = project.ProjectName;
                    dto.Technology = project.Technology;
                    dto.ProjectType = project.ProjectType;
                    dto.UserId = project.UserId;
                    dto.StartDate = project.StartDate;
                    dto.EndDate = project.EndDate;
                    dto.Cost = project.Cost;
                }
    
                return dto;
            }
    
            public List<DtoProject> GetProjectsByUserId(string userid)
            {
                var dtos = new List<DtoProject>();
    
                using (var context = new ProjectManagementContext(_options))
                {
                    
                    dtos = (from a in context.Projects.Where(a => a.UserId.Contains(userid))
                        select new DtoProject
                        {
                            ProjectId = a.ProjectId,
                            ClientName = a.ClientName,
                            ProjectName = a.ProjectName,
                            Technology = a.Technology,
                            ProjectType = a.ProjectType,
                            UserId = a.UserId,
                            StartDate = a.StartDate,
                            EndDate = a.EndDate,
                            Cost = a.Cost
                        }).ToList();
                }
    
                return dtos;
            }
    
            public void CreateProject(DtoProject dto)
            {
                using (var context = new ProjectManagementContext(_options))
                {
                    var project = new Projects
                    {
                        ClientName = dto.ClientName,
                        ProjectName = dto.ProjectName,
                        Technology = dto.Technology,
                        ProjectType = dto.ProjectType,
                        UserId = dto.UserId,
                        StartDate = dto.StartDate,
                        EndDate = dto.EndDate,
                        Cost = dto.Cost
                    };
    
                    context.Projects.Add(project);
                    context.SaveChanges();
               }
            }
    
            public void UpdateProject(DtoProject dto)
            {
                var project = new Projects();
                
                using (var context = new ProjectManagementContext(_options))
                {
                   project = (context.Projects.Where(a => a.ProjectId == dto.ProjectId)).SingleOrDefault();
                }
    
                if (project != null)
                {
                    project.ClientName = dto.ClientName;
                    project.ProjectName = dto.ProjectName;
                    project.Technology = dto.Technology;
                    project.ProjectType = dto.ProjectType;
                    project.UserId = dto.UserId;
                    project.StartDate = dto.StartDate;
                    project.EndDate = dto.EndDate;
                    project.Cost = dto.Cost;
                }
    
                using (var dbcontext = new ProjectManagementContext(_options))
                {
                    if (project == null) return;
                    dbcontext.Entry(project).State = EntityState.Modified;
                    dbcontext.SaveChanges();
                }
            }
    
            public void DeleteProject(int id)
            {
                Projects project;
    
                using (var context = new ProjectManagementContext(_options))
                {
                   project = (context.Projects.Where(a => a.ProjectId == id)).SingleOrDefault();
                }
    
                if (project == null) return;
    
                using (var newContext = new ProjectManagementContext(_options))
                {
                   
                    var tasks = new DaoTask(_options).GetTasksByProjectId(project.ProjectId);
                    using (TransactionScope scope = new TransactionScope())
                    {
                        foreach (var task in tasks)
                        {
                            new DaoTask(_options).DeleteTask(task.TaskId);
                        }
    
                        newContext.Entry(project).State = EntityState.Deleted;
                        newContext.SaveChanges();
    
                        scope.Complete();
                    }
                }
            }
        }
    }
    
    
    using System;
    
    namespace Entities
    {
        public class DtoProject
        {
            public int ProjectId { get; set; }
            public string ClientName { get; set; }
            public string ProjectName { get; set; }
            public string Technology { get; set; }
            public string ProjectType { get; set; }
            public string UserId { get; set; }
            public DateTime StartDate { get; set; }
            public DateTime EndDate { get; set; }
            public decimal Cost { get; set; }
        }
    }

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, December 31, 2018 7:07 AM
  • User1930269528 posted

    good idea, but what is the question here?

    Monday, December 31, 2018 7:29 AM
  • User521171331 posted

    @DA924, I haven't break it up into more layers like interface and etc. Now, I have only two simple project: one for front end, one for the back-end (Web API). 

    What makes me wonder is the model below appear in both projects. To avoid repetition, I was thinking to use one set instead of appearing in both projects. But, I think I got one good point from you, which is ViewModel. I do understand ViewModel concept. I think the model in my front-end should be a ViewModel instead of a normal domain model. Am I right?

    public class Employee
        {
            public int EmployeeID { get; set; }
    
            [Required(ErrorMessage="This Field is Required")]
            public string Name { get; set; }
            public string Position { get; set; }
            public Nullable<int> Age { get; set; }
            public Nullable<int> Salary { get; set; }
        }

    Monday, December 31, 2018 8:37 AM
  • User521171331 posted

    If I have this ViewModel,

    public class ChangePinForm
        {
            [Range(100000, 999999), Display(Name = "Enter Current Card Pin")]
            [DataType(DataType.Password)]
            public int OldCardPin { get; set; }
    
            [Range(100000, 999999), Display(Name = "Enter New Card Pin")]
            [DataType(DataType.Password)]
            public int NewCardPin { get; set; }
    
            [Range(100000, 999999), Display(Name = "Enter New Card Pin Again")]
            [DataType(DataType.Password)]
            public int ConfirmNewCardPin { get; set; }
        }

    my controller without Web API will be something like below,

    [HttpPost]
            public ActionResult ChangePin(ChangePinForm changePinForm)
            {
                selectedBankAccount = db.BankAccounts.Find(Session["userid"]);
                if (changePinForm.OldCardPin != selectedBankAccount.PinCode)
                {
                    ViewBag.Error = "Please key in the correct current pin number.";
                    return View();
                } else if (changePinForm.NewCardPin != changePinForm.ConfirmNewCardPin)
                {
                    ViewBag.Error = "New card pin number and Confirm new card pin number do not match.";
                    return View();
                } else
                {
                    selectedBankAccount.PinCode = changePinForm.ConfirmNewCardPin;
                    db.SaveChanges();
                    return View("Done");
                }
                
            }

    But if I use Web API controller in another project, how will it know my ViewModel class (example, ChangePinForm) name since my ViewModel class is defined in the Front-end (MVC which consume the Web API)

    Monday, December 31, 2018 9:01 AM
  • User1120430333 posted

    @DA924, I haven't break it up into more layers like interface and etc. Now, I have only two simple project: one for front end, one for the back-end (Web API).


    What makes me wonder is the model below appear in both projects. To avoid repetition, I was thinking to use one set instead of appearing in both projects. But, I think I got one good point from you, which is ViewModel. I do understand ViewModel concept. I think the model in my front-end should be a ViewModel instead of a normal domain model. Am I right?

    Yes the VM is used by the view. The VM is passed between the controller and the view. You should understand SoC and MVC.

    https://en.wikipedia.org/wiki/Separation_of_concerns

    https://www.c-sharpcorner.com/UploadFile/56fb14/understanding-separation-of-concern-and-Asp-Net-mvc/

    Monday, December 31, 2018 1:49 PM
  • User521171331 posted

    ok thanks.

    Monday, December 31, 2018 2:58 PM
  • User521171331 posted

    By the way, I got the solution already but haven't try.

    I need to have ViewModel in both projects.

    Just simply receive the object in your API in the back-end, something like

    [HttpPost("changepin")]
    public ActionResult ChangePin([FromBody] ChangePinForm changePinForm)

    This is going to reference ChangePinForm from a separate library (i suggest to use .net standard 2.0) so you can both reference from .net core and .net framework

     

    Monday, December 31, 2018 3:09 PM
  • User1120430333 posted

    But if I use Web API controller in another project, how will it know my ViewModel class (example, ChangePinForm) name since my ViewModel class is defined in the Front-end (MVC which consume the Web API)

    The WebAPI is a service that should be consumable by any type of program that acts as a client to the WebAPI. The WebAPI doesn't care what type of program consumes it as long as the client program to the WebAPI understands its request and response contract.

    Your  other problem is that you are not following MVC principles where the controller calls a object in the model namespace for CRUD operation with the database and you have the controller doing database activates. Also the model object populates the VM.

    Also you you should implement the DTO pattern for the MVC WebAPI client and the WebAPI service as the DTO travels between the two.

    Monday, December 31, 2018 4:43 PM
  • User1120430333 posted

    I need to have ViewModel in both projects

    Just simply receive the object in your API in the back-end, something like

    Again, the viewmodel's job is to work with a view in MVC. The VM is not to be traveling anywhere. The DTO's job is to hold data and travel between layers, tiers or processes.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, December 31, 2018 4:51 PM
  • User521171331 posted

    Thanks. Got it.

    Tuesday, January 1, 2019 12:19 AM
  • User521171331 posted

    Hi , just one more question. This DTO class will be another separate project?

    Tuesday, January 1, 2019 12:28 AM
  • User1120430333 posted

    Hi , just one more question. This DTO class will be another separate project?

    Now, you could  go to each project and make the DTO or DTO(s) for each project. But the problem with that is if one or more DTO(s) change, it means that you would have to go to each project and make the changes. That seems like a lot of work. On the other hand, if you put the DTO(s) in a classlib project, then all the DTO(s) are in one spot, all the other projects just set reference to the classlib project's DLL and they all know about the change to the DTO, becuase it at one spot in the referenced classlib project's DLL.

    Capiche?

    Tuesday, January 1, 2019 2:57 AM
  • User1520731567 posted

    Hi ngaisteve1,

    Hi , just one more question. This DTO class will be another separate project?

    Yes,you better separate web api and mvc to make them into two projects.

    Web api focuses on getting various data from the database

    MVC is responsible for business logic and page design and so on.

    You need to retrieve data in web api  according to different business logic,

    and design various flexible interfaces in mvc to receive the data source of webapi.

    Best Regards.

    Yuki Tao

    Tuesday, January 1, 2019 9:05 AM
  • User521171331 posted

    @DA924, yeah got it. thanks.

    Tuesday, January 1, 2019 1:21 PM