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:
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.
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.
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; }
}
}
If you find the post has answered your issue, then please mark post as 'answered'.
@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; }
}
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)
@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.
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
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.
If you find the post has answered your issue, then please mark post as 'answered'.
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.
If you find the post has answered your issue, then please mark post as 'answered'.
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?
If you find the post has answered your issue, then please mark post as 'answered'.
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
MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue.
If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.
Member
468 Points
820 Posts
How to reference to external dll for model?
Dec 31, 2018 01:19 AM|ngaisteve1|LINK
Hi,
I have my two projects in my solution.
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
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"; } } }
Contributor
4863 Points
4120 Posts
Re: How to reference to external dll for model?
Dec 31, 2018 07:07 AM|DA924|LINK
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.....
Member
430 Points
122 Posts
Re: How to reference to external dll for model?
Dec 31, 2018 07:29 AM|ehsansajjad465|LINK
good idea, but what is the question here?
Member
468 Points
820 Posts
Re: How to reference to external dll for model?
Dec 31, 2018 08:37 AM|ngaisteve1|LINK
@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?
Member
468 Points
820 Posts
Re: How to reference to external dll for model?
Dec 31, 2018 09:01 AM|ngaisteve1|LINK
If I have this ViewModel,
my controller without Web API will be something like below,
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)
Contributor
4863 Points
4120 Posts
Re: How to reference to external dll for model?
Dec 31, 2018 01:49 PM|DA924|LINK
@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/
Member
468 Points
820 Posts
Re: How to reference to external dll for model?
Dec 31, 2018 02:58 PM|ngaisteve1|LINK
ok thanks.
Member
468 Points
820 Posts
Re: How to reference to external dll for model?
Dec 31, 2018 03:09 PM|ngaisteve1|LINK
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
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
Contributor
4863 Points
4120 Posts
Re: How to reference to external dll for model?
Dec 31, 2018 04:43 PM|DA924|LINK
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.
Contributor
4863 Points
4120 Posts
Re: How to reference to external dll for model?
Dec 31, 2018 04:51 PM|DA924|LINK
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.
Member
468 Points
820 Posts
Re: How to reference to external dll for model?
Jan 01, 2019 12:19 AM|ngaisteve1|LINK
Thanks. Got it.
Member
468 Points
820 Posts
Re: How to reference to external dll for model?
Jan 01, 2019 12:28 AM|ngaisteve1|LINK
Hi , just one more question. This DTO class will be another separate project?
Contributor
4863 Points
4120 Posts
Re: How to reference to external dll for model?
Jan 01, 2019 02:57 AM|DA924|LINK
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?
Contributor
3710 Points
1431 Posts
Re: How to reference to external dll for model?
Jan 01, 2019 09:05 AM|Yuki Tao|LINK
Hi ngaisteve1,
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
Please remember to click "Mark as Answer" the responses that resolved your issue.
If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.
Member
468 Points
820 Posts
Re: How to reference to external dll for model?
Jan 01, 2019 01:21 PM|ngaisteve1|LINK
@DA924, yeah got it. thanks.