2014-06-28 19 views
8

Wykonuję samouczki i próbuję się nauczyć najlepszej praktyki, jeśli chodzi o rozwój MVC. Projekt, którego używam poniżej, pochodzi z Pro ASP.Net MVC5 autorstwa Apress/Adam Freeman. Jak dotąd wszystko idzie dobrze ... ale wciąż nie jestem w stanie poradzić sobie z pracą z kontrolerami. Tak, rozumiem pojęcie Kontrolerów, ale wciąż walczę, jeśli chodzi o metody post i get. Oto przykładowy przepływ mojej aplikacji MVC:Przykład MVC ViewModel

Mój projekt app.Domain

Mam tabeli użytkownika w bazie danych i odniesienie jej Podmiotów/Users.cs

using System; 
using System.Collections.Generic; 
using System.ComponentModel.DataAnnotations; 

namespace app.Domain.Entities 
{ 
public class Users 
{ 
    [Key] 
    public int UserID { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string Email { get; set; } 
    public string City { get; set; } 
    public string State { get; set; } 
    public DateTime CreateDate { get; set; } 
    public DateTime LastLogin { get; set; } 

} 
} 

Następnie, mieć interfejs i jest położony Streszczenie/IUsersRepository.cs

using System; 
using System.Collections.Generic; 
using app.Domain.Entities; 

namespace app.Domain.Abstract 
{ 
public interface IUsersRepository 
{ 
    IEnumerable<Users> Users { get; } 
} 
} 

poruszające, teraz wypełnić moje podmioty Beton/EFUsersRepository.cs

using System; 
using System.Collections.Generic; 
using app.Domain.Entities; 
using app.Domain.Abstract; 

namespace app.Domain.Concrete 
{ 
public class EFUsersRepository : IUsersRepository 
{ 
    private EFDbContext context = new EFDbContext(); 

    public IEnumerable<Users> Users 
    { 
     get { return context.Users; } 
    } 
} 
} 

Ponadto, podręcznik używa Ninjecta, który rozumiem i wszystko jest poprawnie powiązane. Nie opublikuję tego kodu, chyba że ktoś mnie o to poprosi.

Oto moje rozwiązanie app.WebUI:

Podręcznik podchodzi do mnie poprzez tworzenie ViewModel. Tutaj sprawy stają się dla mnie trochę niewyraźne. Czy ViewModel jest dodatkowym kanałem do pozyskiwania obiektów? Zamiast odwoływania się do samych modeli, czy zawsze powinienem tworzyć ViewModels, aby WYBRAĆ, UPDATE, INSERT, DELETE dane (Models/UsersViewModel.cs)?

using System; 
using System.Collections.Generic; 
using app.Domain.Entities; 

namespace app.WebUI.Models 
{ 
public class UsersViewModel 
{ 
    //public string FirstName { get; set; } 
    //public string LastName { get; set; } 
    //public string Email { get; set; } 
    //public string City { get; set; } 
    //public string State { get; set; } 
    public IEnumerable<Users> Users { get; set; } 
} 
} 

Scenariusz jest, aby użytkownik mógł wpisać e-mail, a następnie kontroler sprawdza bazę danych do wiadomości e-mail. Jeśli istnieje, przekieruj do widoku Informacje (Controllers/HomeController.cs).

using System.Linq; 
using System.Web.Mvc; 
using app.Domain.Abstract; 
using app.WebUI.Models; 


namespace app.Controllers 
{ 
public class HomeController : Controller 
{ 
    private IUsersRepository repository; 

    public HomeController(IUsersRepository usersRepository) 
    { 
     this.repository = usersRepository; 
    } 

    [HttpGet] 
    public ActionResult Index() 
    { 
     return View(); 
    } 

    [HttpPost] 
    public ActionResult Index() 
    { 
     UsersViewModel userViewModel = new UsersViewModel() 
     { 
      Users = repository.Users 
      .Where(p => p.Email == "[email protected]") 
     }; 
     return View("About", userViewModel); 

    } 

    public ActionResult About() 
    { 
     ViewBag.Message = "Your application description page."; 
     return View(); 
    } 

    public ActionResult Contact() 
    { 
     ViewBag.Message = "Your contact page."; 
     return View(); 
    } 
} 
} 

I tu jest moim zdaniem (Home/Index.cshtml):

@model app.WebUI.Models.UsersViewModel 

@{ 
    ViewBag.Title = "Home Page"; 
    Layout = "~/Views/Shared/_LayoutNoMenu.cshtml"; 
} 


@foreach (var p in Model.Users) 
{ 
<div class="container"> 
@using (Html.BeginForm("About", "Home", FormMethod.Get, new { @class = "begin-form" })) 
{ 
    <h1>Welcome</h1> 
    <div class="required-field-block"> 
    <textarea rows="1" class="form-control" placeholder="Email" id="filter"></textarea> 
    </div> 
    <button class="btn btn-primary" type="submit">Login</button> 
} 
</div> 
} 

Wszelkie porady o tym, jak prawidłowo używać ViewModel?

+2

ViewModel ma reprezentować stan swojej stronie. Na przykład, jeśli masz przycisk radiowy na swojej stronie, viewmodel będzie miał właściwość dla stanu przycisku radiowego. Proste widoki mogą nie mieć żadnej potrzeby dla viewmodelu, jeśli wszystko, co robią, bezpośrednio wyświetla widoki bez dodatkowych rzeczy. –

+0

Dzięki Daniel. Tak więc puste pole tekstowe nie będzie wymagało ViewModel. Ale pole tekstowe, które chcę wypełnić podczas ładowania widoku, powinno korzystać z ViewModel? – JoshYates1980

+0

Mam na myśli zapełnianie danych z bazy danych. – JoshYates1980

Odpowiedz

8

W czerwcu 2014 r. Zadałem to pytanie podczas nauki MVC. Na dzień dzisiejszy rozumiem koncepcję viewmodelu. Mam nadzieję, że to pomoże innym początkującym MVC:

moim modelu, który reprezentuje tabelę bazy danych:

public partial class County : Entity 
{ 
    public int CountyID { get; set; } 
    public string CountyName { get; set; } 
    public string UserID { get; set; } 
    public DateTime? CreatedDate { get; set; } 
    public string ModifiedUserID { get; set; } 
    public DateTime? ModifiedDate { get; set; } 

    public virtual IList<Property> Properties { get; set; } 
    public virtual DistrictOffice DistrictOffice { get; set; } 
    public virtual IList<Recipient> Recipients { get; set; } 
} 

Istnieją dwa jeden-do-wielu i relacja jeden-do-jednego. Struktura encji i wtrysk zależności. (Nie jest to konieczne w przypadku objaśnień związanych z viewmodel.)

Najpierw tworzę model podglądu do tymczasowego przechowywania, aby przejść z kontrolera do widoku. CountyViewModel.cs

public class CountyViewModel 
{ 
    [HiddenInput] 
    public int? CountyId { get; set; } 

    [DisplayName("County Name")] 
    [StringLength(25)] 
    public string CountyName { get; set; } 

    [DisplayName("Username")] 
    [StringLength(255)] 
    public string Username{ get; set; } 
} 

Masz swobodę używania różnych nazw i typów danych niż model. Na przykład moja kolumna bazy danych to UserID, mój model to UserID, ale mój viewmodel to UserName. I nie trzeba przekazywać danych do widoku, który nie będzie użyty (cały model). Ten przykład wymaga tylko trzech części modelu hrabstwa.

ciągu mojego kontrolera oświadczam, moim zdaniem model:

muszę dane:

var county = _countyService.Get(countyId); 

Następnie

CountyViewModel countyViewModel = new CountyViewModel(); 
countyViewModel.CountyId = county.CountyID; 
countyViewModel.CountyName = county.CountyName; 
countyViewModel.UserName = county.UserID; 

Można również zadeklarować ten sposób:

CountyViewModel countyViewModel = new CountyViewModel 
{ 
    CountyId = county.CountyID, 
    CountyName = county.CountyName, 
    UserName = county.UserID 
}; 

Teraz jest Czas przejść na widoku:

return View(countyViewModel); 

w widoku:

@model Project.Web.ViewModels.CountyViewModel 

@{ 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 

<div>@Model.CountyName</div> 
@Html.HiddenFor(model => model.CountyId) 

<div> 
@Html.TextBoxFor(model => model.CountyName, new { @class = "form-control" }) 

Oto prosty przykład przekazywania danych przy użyciu ViewModel i korzystania z usługi połączeń do bazy danych z Entity Framework:

Przykład Kontroler

public class PropertyController : Controller 
{ 
    private readonly ICountyService _countyService; 

    public PropertyController(ICountyService countyService) 
     : base() 
    { 
     _countyService = countyService; 
    } 


    [HttpGet] 
    public ActionResult NewProperty() 
    { 
     using (UnitOfWorkManager.NewUnitOfWork()) 
     { 
      ListAllCountiesViewModel listAllCountyViewModel = new ListAllCountiesViewModel() 
      { 
       ListAllCounty = _countyService.ListOfCounties().ToList() 
      }; 

      PropertyViewModel viewModel = new PropertyViewModel() 
      { 
       _listAllCountyViewModel = listAllCountyViewModel, 
       _countyViewModel = new CountyViewModel(), 
      }; 
      return View(viewModel); 
     } 
    } 
} 

Przykład ViewModels

public class CountyViewModel 
{ 
    [HiddenInput] 
    public int? CountyId { get; set; } 

    [DisplayName("County Name")] 
    [StringLength(25)] 
    public string CountyName { get; set; } 

    [DisplayName("County URL")] 
    [StringLength(255)] 
    public string URL { get; set; } 
} 

public class ListAllCountiesViewModel 
{ 
    public string CountyName { get; set; } 
    public IEnumerable<County> ListAllCounty { get; set; } 
} 

public class PropertyViewModel 
{ 
    public ListAllCountiesViewModel _listAllCountyViewModel { get; set; } 
    public CountyViewModel _countyViewModel { get; set; } 
} 

Przykład Warstwa usług

public partial interface ICountyService 
{ 
    County Get(int id); 
    County GetByCompanyCountyID(int id); 
    IEnumerable<County> ListOfCounties(); 
    void Delete(County county); 
    IEnumerable<State> ListOfStates(); 
    void Add(County county); 
    County SearchByName(string county); 
} 


public partial class CountyService : ICountyService 
{ 
    private readonly ICountyRepository _countyRepository; 

    public CountyService(ICountyRepository countryRepository) 
    { 
     _countyRepository = countryRepository; 
    } 

    /// <summary> 
    /// Returns a county 
    /// </summary> 
    /// <param name="id"></param> 
    /// <returns></returns> 
    public County Get(int id) 
    { 
     return _countyRepository.Get(id); 
    } 

    /// <summary> 
    /// Returns a county by County Id 
    /// </summary> 
    /// <param name="id"></param> 
    /// <returns></returns> 
    public County GetByCountyID(int id) 
    { 
     return _countyRepository.GetByMedicaidCountyID(id); 
    } 

    /// <summary> 
    /// Returns all counties 
    /// </summary> 
    /// <returns></returns> 
    public IEnumerable<County> ListOfCounties() 
    { 
     return _countyRepository.ListOfCounties(); 
    } 

    /// <summary> 
    /// Deletes a county 
    /// </summary> 
    /// <param name="county"></param> 
    public void Delete(County county) 
    { 
     _countyRepository.Delete(county); 
    } 

    /// <summary> 
    /// Return a static list of all U.S. states 
    /// </summary> 
    /// <returns></returns> 
    public IEnumerable<State> ListOfStates() 
    { 
     var states = ServiceHelpers.CreateStateList(); 
     return states.ToList(); 
    } 

    /// <summary> 
    /// Add a county 
    /// </summary> 
    /// <param name="county"></param> 
    public void Add(County county) 
    { 
     county.CreatedUserID = System.Web.HttpContext.Current.User.Identity.Name; 
     county.CreatedDate = DateTime.Now; 
     _countyRepository.Add(county); 
    } 

    /// <summary> 
    /// Return a county by searching it's name 
    /// </summary> 
    /// <param name="county"></param> 
    /// <returns></returns> 
    public County SearchByName(string county) 
    { 
     return _countyRepository.SearchByName(county); 
    } 
} 

Przykład Repository warstwa

public partial class CountyRepository : ICountyRepository 
{ 
    private readonly Context _context; 

    public CountyRepository(IContext context) 
    { 
     _context = context as Context; 
    } 

    public County Get(int id) 
    { 
     return _context.County.FirstOrDefault(x => x.CountyID == id); 
    } 

    public County GetByCompanyCountyID(int id) 
    { 
     return _context.County.FirstOrDefault(x => x.CountyID == id); 
    } 

    public IList<County> ListOfCounties() 
    { 
     return _context.County.ToList() 
      .OrderBy(x => x.CountyName) 
      .ToList(); 
    } 

    public void Delete(County county) 
    { 
     _context.County.Remove(county); 
    } 

    public County Add(County county) 
    { 
     _context.County.Add(county); 
     return county; 
    } 

    public County SearchByName(string county) 
    { 
     return _context.County.FirstOrDefault(x => x.CountyName == county); 
    } 
} 
+0

Josh, skąd pochodzi "_countyService"? Jedyną wzmianką o tym jest jego użycie. – muybn

+0

Zaktualizowałem swoją odpowiedź na przykładzie tego, jak moja _countyService pobiera dane. – JoshYates1980

+0

Czy te warstwy serwisowe są potrzebne? Nie możesz po prostu zadzwonić do 'DbContext'? – Sinjai

Powiązane problemy