2014-11-25 2 views
0

У меня возникла эта проблема при попытке сохранить элемент в базе данных в моем веб-приложении asp.net mvc4. я три класса перечисленным нижеМодель, оценивающая значение false при сохранении в базе данных

public class Posts 
{ 
    [Key] 
    public int PostID { get; set; } 

    [Required(ErrorMessage="A Title is required for your Post")] 
    [Display(Name="Title")] 
    public string PostTitle { get; set; } 


    [Required(ErrorMessage="This Field is Required")] 
    [Display(Name = "Post")] 
    public string PostContent { get; set; } 

    [Required()] 
    [DataType(DataType.DateTime)] 
    public DateTime PostDate { get; set; } 
    //public int AuthorID { get; set; } 
    //public int CommentID { get; set; } 

    [NotMapped] 
    public virtual List<Comments> Comment { get; set; } 
    public virtual Users user { get; set; } 

} 

и этот класс имеет много к одному отношений с классом пользователей ниже

public class Users 
{ 

    public Users() 
    { 
    } 

    [Key] 
    public int UserID { get; set; } 

    [Required()] 
    public string Firstname { get; set; } 

    [Required()] 
    public string Lastname { get; set; } 

    [Required()] 
    [DataType(DataType.Date, ErrorMessage="Enter a Valid Date")] 
    public DateTime DOB { get; set; } 

    //[Required()] 
    //public string Photo { get; set; } 

    [Required()] 
    public string Sex { get; set; } 

    [Required()] 
    [DataType(DataType.EmailAddress)] 
    public string Email { get; set; } 

    public DateTime RegDate { get; set; } 

    [Required()] 
    [Column("Username")] 
    //[Remote("doesUserNameExist", "Account", HttpMethod = "POST", ErrorMessage = "User name has already been taken. Please enter a different User name.")] 
    public string Username { get; set; } 

    [Required()] 
    [DataType(DataType.Password)] 
    public string Password { get; set; } 

    public string PasswordSalt { get; set; } 

    [System.ComponentModel.DataAnnotations.Compare("Password", ErrorMessage="Passwords do not match")] 
    [DataType(DataType.Password)] 
    //[NotMapped] 
    //public string ConfirmPassword { get; set; } 


    public virtual List<Posts> Post { get; set; } 
    public virtual List<Comments> Comment { get; set; } 

} 

таблицы базы данных для класса Posts.cs имеет поле под названием user_UserID который Я предполагаю, что это хранить идентификатор пользователя, который создает сообщение. Я пытаюсь сохранить сообщения в базу данных, используя приведенный ниже код

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

<fieldset> 
    <legend>Posts</legend> 

    <div class="form-group"> 
     @Html.LabelFor(model => model.PostTitle) 
     @Html.TextBoxFor(model => model.PostTitle, new {@class = "form-control"}) 
     @Html.ValidationMessageFor(model => model.PostTitle) 
    </div> 

    <div class="form-group"> 
     @Html.LabelFor(model => model.PostContent) 
     @Html.TextAreaFor(model => model.PostContent, new {@class = "form-control"}) 
     @Html.ValidationMessageFor(model => model.PostContent) 
    </div> 
     <input type="hidden" name="user.UserID" value="@Session["LoggedUserID"]" /> 

    <div> 
     <input type="submit" value="Submit" /> 
    </div> 
</fieldset> 

}

Как вы можете видеть, идентификатор пользователя я коплю в таблицу базы данных получаются из идентификатора пользователя, хранящийся в переменной Session["LoggedUserID"]. Контроллер, который обрабатывает сохранение ниже

public class PostsController : Controller 
{ 
    // 
    // GET: /Posts/ 
    BlogContext db = new BlogContext(); 
    public ActionResult Index() 
    { 
     return View(); 
    } 

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

    [HttpPost] 
    public ActionResult Create(Posts Post) 
    { 
     var errors = ModelState.Values.SelectMany(v => v.Errors); 
     try 
     { 
      if (ModelState.IsValid) 
      { 
       var newPost = db.Post.Create(); 
       newPost.PostTitle = Post.PostTitle; 
       newPost.PostContent = Post.PostContent; 
       newPost.PostDate = DateTime.Now; 
       newPost.user.UserID = Post.user.UserID; 
       db.Post.Add(newPost); 
       db.SaveChanges(); 
       return RedirectToAction("Index", "Posts"); 
      } 
      else 
      { 
       ModelState.AddModelError("", "Something is wrong with the model"); 
      } 
     } 

     catch (NullReferenceException ex) 
     { 
      Debug.WriteLine("Processor Usage" + ex.Message); 
     } 

     return View(); 
    } 

} 

Я приложил контрольную точку к Modelstate.IsValid линии, а затем отлажен, но я заметил, что ModelState всегда вычисляемые ложно и ModelState.AddModelError показывает, что есть что-то неправильно с проверкой модель. Ive пробовал все возможные корректировки, все безрезультатно. Мне нужна помощь. Как сохранить записи в таблице базы данных без этой проблемы. Пожалуйста, что я делаю неправильно?

+0

В оценить значение 'ModelState', чтобы увидеть, что является недопустимым свойством. Обратите внимание, что вы не должны отображать скрытый ввод для пользователя в представлении. Просто получите это в методе контроллера, когда вы отправляете сообщение назад. В любом случае вы должны использовать модель представления, содержащую только 2 свойства, которые вы хотите изменить. –

+0

@StephenMuecke, когда я заменил скрытое поле в представлении вызовом контроллера, user.UserID возвращал значение null. И как я могу использовать модель представления, чтобы содержать только два свойства, которые я хочу изменить? Пожалуйста помоги! – ibnhamza

+0

Зачем вам нужно значение 'user.UserID' в представлении? Проблема, я думаю, в том, что вы передаете значение для 'user.UserID', которое заставляет' DefaultModelBinder' инициализировать свойство 'user', которое затем будет содержать ошибки ModelState из-за атрибутов проверки, которые вы применили к' User'. Но я не могу быть уверен, так как вы, похоже, не хотите проверять «ModelState», чтобы увидеть, что такое ошибки! –

ответ

0

Я подозреваю ModelState недействительно, потому что вы публикуете значение для user.UserId (скрытого входа), который инициализирует свойство User которое неверно из атрибутов проверки, применяемых к другим свойствам User. Было бы лучше создать модель представления для создания новых Posts, которые содержат только те свойства, которые вам нужно отображать/редактировать. Не надо включать в себя свойство для User (автора поста), так как это может быть установлено в контроллере при сохранении данных (аналогично тому, что вы делаете для PostDate собственности

Посмотреть модель

public class PostVM 
{ 
    [Required(ErrorMessage="A Title is required for your Post")] 
    [Display(Name="Title")] 
    public string Title { get; set; } 
    [Required(ErrorMessage="This Field is Required")] 
    [Display(Name = "Post")] 
    public string Content { get; set; } 
} 

контроллер

[HttpGet] 
public ActionResult Create() 
{ 
    PostVM model = new PostVM(); 
    return View(model); 
} 

[HttpPost] 
public ActionResult Create(PostVM model) 
{ 
    if(!ModelState.IsValid) 
    { 
    return View(model); 
    } 
    // Initialize new Posts 
    // Map properties from the view model, set the user and date 
    // Save and redirect 
} 

Посмотреть

@model PostVM 
@using (Html.BeginForm()) { 
    .... 
    <div class="form-group"> 
    @Html.LabelFor(model => model.Title) 
    @Html.TextBoxFor(model => model.Title, new {@class = "form-control"}) 
    @Html.ValidationMessageFor(model => model.Title) 
    </div> 
    <div class="form-group"> 
    @Html.LabelFor(model => model.Content) 
    @Html.TextAreaFor(model => model.Content, new {@class = "form-control"}) 
    @Html.ValidationMessageFor(model => model.Content) 
    </div> 
    <input type="submit" value="Submit" /> 
} 
+0

Большое спасибо за вашу помощь. Вы открыли мне глаза на некоторые лучшие практики в mvc. Но это мой первый опыт работы с моделью просмотра, и я вижу причину, почему это должно быть сделано с моделью просмотра. Но что теперь является функцией моей модели домена? Я имею в виду класс Post.cs. Также будет ли пользовательский идентификатор, хранящийся в сеансе, доступным в контроллере, чтобы я мог хранить его в базе данных в качестве автора сообщений ?. Еще одна вещь, что вы подразумеваете под «свойствами карты из ViewModel?». Извините, если я говорю глупо! но я буду очень признателен вам, если вы сможете заставить меня понять этот материал. – ibnhamza

+0

Вы должны всегда использовать модель представления для редактирования данных. [Что такое модель представления в MVC] (http://stackoverflow.com/questions/11064316/what-is-viewmodel-in-mvc). Модель просмотра специфична для MVC и представления. Ваша модель домена по-прежнему важна и сопоставляется с вашей базой данных и может быть использована в приложении WinForms или WPF. Да, сеанс доступен в контроллере (и именно там вы должны получить к нему доступ, а не из представления). Но вы должны добавить это в свой файл cookie проверки подлинности формы. –

+0

При сопоставлении я имею в виду копирование данных из модели представления в модель данных 'dataModel.Property = viewModel.Property' (как и в вашем вопросе с помощью' newPost.PostTitle = Post.PostTitle; '). Вы должны рассмотреть возможность использования таких инструментов, как [automapper] (https://github.com/AutoMapper/AutoMapper), чтобы сделать это проще. –

Смежные вопросы