#asp.net-mvc-3 #ef-code-first
#asp.net-mvc-3 #ef-code-first
Вопрос:
У меня есть добавить представление, которое загружает файл, который является элементом Question
класса
@model PasmISO.Domain.Question
@using (Html.BeginForm("Add", "Photo", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="editor-field">
@Html.TextAreaFor(model => model.QuestionRevisions.First().Content)
@Html.ValidationMessageFor(model => model.QuestionRevisions.First().Content)
</div>
<input type="file" name="file" id="file" />
<br/>
<input type="submit" value="Ask" />
}
У меня есть 2 действия в моем контроллере
Первое действие — это когда пользователь нажимает на кнопку Добавить и получает форму для загрузки фотографии:
public ActionResult Add()
{
db.Users.Add(new User() { Avatar = new Avatar() { Link = new Uri("http://myUrl/../..") }, CreationDate = DateTime.Now, LastActivityDate = DateTime.Now, LastLoginDate = DateTime.Now });
db.SaveChanges();
db.Users.Local.First().Questions = new Collection<Question>() { new Question() };
var question = new Question();
question.QuestionRevisions = new Collection<QuestionRevision>();
var questionRevision = new QuestionRevision();
questionRevision.Tags = new Collection<Tag>();
question.QuestionRevisions.Add(questionRevision);
return View(question);
}
и второе действие, которое срабатывает, когда пользователь принимает форму:
[HttpPost]
public ActionResult Add(Question containers, HttpPostedFileBase file)
{
Проблема в том, что я вижу, что Question
у него нет questionrevisions (равно нулю)
Почему этот объект сбрасывается?
У меня есть поле в контроллере:
PasmISOContext db = new PasmISOContext();
Вот класс Question
вопрос об открытом классе { [Key] public int Id { get; set; }
public virtual User Creator { get; set; }
public int CreatorId { get; set; }
public int PhotoId { get; set; }
public virtual ICollection<QuestionRevision> QuestionRevisions { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
public virtual ICollection<QuestionVote> Votes { get; set; }
public virtual Photo Photo { get; set; }
}
Вот определение моего контекста:
public class PasmISOContext : DbContext
{
public DbSet<Avatar> Avatars { get; set; }
public DbSet<User> Users { get; set; }
public DbSet<Question> Questions { get; set; }
public DbSet<QuestionRevision> QuestionRevisions { get; set; }
public DbSet<Photo> Photos { get; set; }
public DbSet<Achievement> Achievements { get; set; }
public DbSet<Comment> Comments { get; set; }
public DbSet<Tag> Tags { get; set; }
public DbSet<QuestionVote> QuestionVotes { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
Ответ №1:
Причина, по которой QuestionRevisions не привязывается должным образом, заключается в том, что соответствующее поле textarea не имеет правильного имени, чтобы связыватель модели по умолчанию мог его привязать. Вы можете взглянуть на следующее сообщение в блоге, объясняющее, какой правильный формат проводника для коллекций.
Итак, чтобы устранить проблему, одна из возможностей — изменить тип в вашей модели представления с ICollection<QuestionRevision>
на IList<QuestionRevision>
, чтобы у вас был доступ индексатора к элементам коллекции, а затем в представлении просто:
<div class="editor-field">
@Html.TextAreaFor(x => x.QuestionRevisions[0].Content)
@Html.ValidationMessageFor(x => x.QuestionRevisions[0].Content)
</div>
Теперь сгенерированный HTML-код будет выглядеть так:
<div class="editor-field">
<textarea cols="20" name="QuestionRevisions[0].Content" id="QuestionRevisions_0__Content" rows="2">Some value</textarea>
<span class="field-validation-valid" data-valmsg-for="QuestionRevisions[0].Content" data-valmsg-replace="true"></span>
</div>
Обратите внимание, как имя текстовой области соответствует проводному формату, ожидаемому связующим элементом модели по умолчанию для работы с коллекциями. Теперь, когда вы отправляете форму QuestionRevisions
, список будет правильно привязан и будет содержать один элемент.