2013-06-18 18 views
29

Lütfen noobness numaramdan ayırarak MVC modeline çok yeniyim. Ben sitemde kayıtlı kullanıcılar için bir profil bilgileri sayfası inşa ediyorumMVC 4 - Kısmi görünümde farklı bir model kullanın

yapmaya çalışıyorum ne

. Bu sayfa kullanıcının doğum tarihi, telefon numarası, abonelik durumu vb. Ile ilgili verilerini listeleyecektir. Aynı zamanda kullanıcıların parolalarını, e-posta adreslerini ve kişisel bilgilerini aynı sayfada değiştirmelerini sağlamak için bir form olmasını isterim.

Benim sorunum kullanıcının veri geride bırakmış modeli değişkeni yoluyla benim denetleyicisi geliyor

:

public ActionResult Profil() 
     { 
      var model = db.Users.First(e => e.UserName == WebSecurity.CurrentUserName); 
      return View(model); 
     } 
çıktı Bence şöyle

:

<label>Phone number: </label> 
      @if (Model.PhoneNumber != null) 
        { 
         @Model.PhoneNumber 
        } 
        else 
        { 
         <span class="red">You haven't set up your phone number yet. </span> 
        } 

formu Kullanıcının bilgisini değiştirebileceği başka bir model olan ProfileModel kullanırdı. Bu yüzden temel bilgilerim, biri bilgi çıkışı için ve veri göndermek için bir tane olmak üzere iki model kullanmam gerekiyor.

@using (Html.BeginForm()) 
    { 
     @Html.AntiForgeryToken() 
     @Html.ValidationSummary() 

     @Html.Partial("_ModifyProfileInfo") 
    } 

İşte kısmi görünümü var:

İşte

The model item passed into the dictionary is of type 'Applicense.Models.User', but this dictionary requires a model item of type 'Applicense.Models.ProfileModel'.

gibi kısmi görünümüne çağrım görünüyor:

Ben kısmi görünümünü kullanarak bunu elde edebilirsiniz, ama bu hatayı alıyorum düşündüm

public class ProfileModel 
    { 
     [Required] 
     [DataType(DataType.EmailAddress)] 
     [Display(Name = "New e-mail address")] 
     public string Email { get; set; } 

     [DataType(DataType.EmailAddress)] 
     [Display(Name = "Confirm new e-mail address")] 
     [Compare("Email", ErrorMessage = "The e-mail and it's confirmation field do not match.")] 
     public string ConfirmEmail { get; set; } 
    } 
: sonunda burada
@model Applicense.Models.ProfileModel 
<ul> 
    <li> 
     @Html.LabelFor(m => m.Email) 
     @Html.EditorFor(m => m.Email) 
    </li> 
    <li> 
     @Html.LabelFor(m => m.ConfirmEmail) 
     @Html.EditorFor(m => m.ConfirmEmail) 
    </li> 
    <input type="submit" value="Update e-mail" /> 
</ul> 

Ve benim ProfileModel var

Bir şey mi eksik? Bunu yapmanın doğru yolu nedir?

Düzenleme: Kodumu Nikola Mitev'in yanıtını yansıtan bir remotum var, ama şimdi başka bir sorunum var. Benim elde hata var: Ben değiştirilen e-mail adresi değerleri gönderme olduğumda

Object reference not set to an instance of an object. (@Model.UserObject.LastName)

Bu yalnızca oluşur. İşte benim ViewModel (ProfileModel.cs) var:

public class ProfileModel 
    { 
     public User UserObject { get; set; } 

     [Required] 
     [DataType(DataType.EmailAddress)] 
     [Display(Name = "Új e-mail cím")] 
     public string Email { get; set; } 

     [DataType(DataType.EmailAddress)] 
     [Display(Name = "Új e-mail cím megerősítése")] 
     [Compare("Email", ErrorMessage = "A két e-mail cím nem egyezik.")] 
     public string ConfirmEmail { get; set; } 

     [DataType(DataType.EmailAddress)] 
     [Display(Name= "E-mail cím")] 
     public string ReferEmail { get; set; } 
    } 

Denetleyici: sonunda burada

public ActionResult Profil() 
     { 
      var User = db.Users.First(e => e.UserName == WebSecurity.CurrentUserName); 

      var ProfileViewModel = new ProfileModel 
      { 
       UserObject = User 
      }; 

      return View(ProfileViewModel); 
     } 

Ve olması benim user.cs modeli sınıfı:

[Table("UserProfile")] 
    public class User 
    { 
     [Key] 
     [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
     public int UserId { get; set; } 
     [Column("UserName")] 
     public string UserName { get; set; } 
     [Column("Email")] 
     [Required] 
     public string Email { get; set; } 
     [Column("FirstName")] 
     public string FirstName { get; set; } 
     [Column("LastName")] 
     public string LastName { get; set; } 
     [Column("PhoneNumber")] 
     public string PhoneNumber { get; set; } 
... You get the idea of the rest... 

manken olduğu için oluyor düşünüyorum Her bir required sütununa veriyi veritabanına koymaya çalışıyor.

Edit2: benim profile eylem HttpPost yöntemi:

Kumandanızda tanımlandığı haliyle ViewData göndermenizi sağlar @Html.Partial bir aşırı yük vardır
[HttpPost] 
     [Authorize] 
     [ValidateAntiForgeryToken] 
     public ActionResult Profil(ProfileModel model) 
     { 
      if (ModelState.IsValid) 
      { 
//insert into database 
       return Content("everything's good"); 
      } 
      else 
      { 
//outputs form errors 
       return View(model); 
      } 
     } 

cevap

35

bu durumun kullanmak ve Profil denetleyiciye ViewModel geçmektir işlemek için en iyi yolu içinde, ViewModel size görünümüne geçmek istediğiniz birden nesneler için sarıcı sınıftır.

public class ProfileUserViewModel 
{ 
    public ProfileModel ProfileModelObject {get; set;} 
    public UserModel UserModelObject {get; set;} 
} 

Kişisel denetleyicisi gibi görünmelidir: nihayet

public ActionResult Profil() 
{    
    var profileModel = db.Users.First(e => e.UserName == WebSecurity.CurrentUserName); 
    var userModel = //fetch from db. 

    var pmViewModel = new ProfileUserViewModel 
          { 
           ProfileModelObject = profileModel, 
           UserModelObject = userModel 
          }; 

    return View(pmViewModel); 
} 

Ve görünümü: [HttpPost] profil fonksiyonunda

@model Applicense.Models.ProfileUserViewModel 

<label>Phone number: </label> 

@if (Model.ProfileModelObject.PhoneNumber != null) 
{ 
    @Model.PhoneNumber 
} 
else 
{ 
    <span class="red">You haven't set up your phone number yet. </span> 
} 
+2

teşekkür ederiz sizin için hazır hale bir cazibe gibi çalışır! :) Çok iyi yazılmış cevap için de +1. – PeterInvincible

+0

Şimdi başka bir hata alıyorum :(Soruyu yanıtlamak için onu düzenledim – PeterInvincible

+0

@Tharline Getirmeye çalıştığınız belirli bir kaydın LastName alanında değeri var mı? –

13

- Bu genellikle için kullanmak yöntemdir kısmi görünümler. Denetleyicinizde 'u ViewDataDictionary olarak tanımlayın. Sonra görünümü

@Html.Partial("_ModifyProfileInfo",ViewData["mypartialdata"]) 
1

, modelstate.isvalid yanlış ise, kendi düzenleme görünümünü dönmek fakat pmViewModel'u tekrar tanımlamanız gerekiyor, diğer yandan kısmi görünümünüzün görüntülenecek bir nesnesi olmayacaktır. aşağıdakileri kullanmayı deneyin ve bize ben ancak bazı insanlar hala benzer bir sorunla karşı karşıya olabilir önce bu soruyu Uzun zamandır araları istendi bilirken

[HttpPost] 
[Authorize] 
[ValidateAntiForgeryToken] 
public ActionResult Profil(ProfileModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     //insert into database 
     return Content("everything's good"); 
    } 
    else 
    { 
     //outputs form errors 
     var pmViewModel = new ProfileUserViewModel 
     { 
      ProfileModelObject = profileModel, 
      UserModelObject = userModel 
     }; 

     return View(model); 
    } 
} 
+0

Teşekkürler! Ben herhangi bir görünüm döndürülür önce pmViewModel koymak zorunda kaldı işe almak için – PeterInvincible

+0

'pmViewModel' bildiriyorsunuz ve daha sonra hiç kullanılmıyor, doğru mu? – SharpC

0

ne olur bildirin. Bir sayfada birden fazla görüntüleme modelini geçmek veya kullanmak için kullandığım bir kolay çözüm, ikinci nesneyi tutmak ve buna görünümde başvurmak için bir ViewBag kullanmaktır. Örneğe bakınız feryat. Kumandanızda olarak

bunu:

Obj2 personalDets = new Obj2(); 
DbContext ctx = new DbContext(); 
var details = ctx.GetPersonalInformation; 

foreach(var item in details) { 
    personalDets.Password = item.Password; 
    personalDets .EmailAddress = item.EmailAddress; 
} 

ViewBag.PersonalInformation = personalDets; 

Sonra görünümünde bu özellikler

İlgili konular