2016-03-22 4 views
0

У меня есть вид с названием «Детали», который содержит частичный вид «PostReply». Я пытаюсь передать представление Id из представления Details в действие PostReply Controller.Передача значения Id в частичный вид

Я пробовал это в подробном представлении, но он толкает нулевое значение id.

@Html.Partial("PostReply", new XXXXX.Models.Reply{ QuestionId = Model.Question.ID }) 

Затем я попытался добавить значение идентификатора для BeginForm в PostReply (Partial View), как это:

Html.BeginForm("PostReply", "Question", new { id = Model.Question.ID})) 

Это также не работает. Как я могу получить значение id из деталей в PostReply? Заранее спасибо.

Детали Вид:

@model XXXXXX.Models.ParentView.Questions 
.... 
@Html.DisplayNameFor(model => model.QuestionModel.Title) 
@Html.DisplayNameFor(model => model.QuestionModel.Desc) 
.... 
@Html.ActionLink("Edit", "Edit", new { id = Model.QuestionModel.ID }) | 
     @Html.ActionLink("Back to List", "Index") 
.... 
@Html.Partial("PostReply", new Chemtalks.Models.Reply()) 

PostReply (Частичный вид):

@model XXXXX.Models.Reply 
@using (Html.BeginForm("PostReply", "Question", FormMethod.Post)) 
{ 
    @Html.LabelFor(model => model.ReplyText) 
    @Html.EditorFor(model => model.ReplyText) 
    @Html.ValidationMessageFor(model => model.ReplyText 

    <input type="submit" value="Create" class="btn btn-default" /> 
} 

Детали & PostReply Контроллеры:

public ActionResult Details(int? id) 
{ 
    if (id == null) 
    { 
     return new HttpStatusCodeResult(HttpStatusCode.BadRequest); 
    } 
    var model = new ParentView.Questions 
    { 
     QuestionModel = db.QuestionModels.Find(id), 
     Reply = db.Replies.Where(t => t.QuestionId == id) 
    }; 
    if (model == null) 
    { 
     return HttpNotFound(); 
    } 
    return View(model); 
} 

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult PostReply([Bind(Include = "ReplyID, ReplyText, UserID, QuestionId")] Reply reply, int? id) 
{ 
    try 
    { 
     if (ModelState.IsValid) 
     { 
      reply.QuestionId = id; 
      reply.UserID = User.Identity.GetUserId(); 
      db.Replies.Add(reply); 
      db.SaveChanges(); 
     } 
    } 
    catch (DataException) 
    { 

     ModelState.AddModelError("", "Unable to post your reply. Please try again later."); 
    } 

    return PartialView(reply); 
} 

QuestionModel:

public class QuestionModels 
{ 
    public int ID { get; set; } 
    public string Title { get; set; } 
    public string Desc { get; set; } 
    public string UserID { get; set; } 
    [ForeignKey("QuestionId")] 
    public virtual ICollection<Reply> Replies { get; set; } 
} 

public class Reply 
{ 
    public int ReplyID { get; set; } 
    public string ReplyText { get; set; } 
    public string UserID { get; set; } 
    public int? QuestionId { get; set; } 
    public virtual QuestionModels QuestionsModels { get; set; } 
} 

ParentView Модель:

public class ParentView 
{ 
    public class Questions 
    { 
     public QuestionModels QuestionModel { get; set; } 
     public IEnumerable<Reply> Reply { get; set; } 
    } 
} 
+0

Вы не показали свои модели, но 'новый XXXXX.Models.Reply {QuestionID = Model.Question.ID})' 'означает Reply' содержит свойство с именем' QuestionId', так что я предполагаю, ваш хочу 'new {id = Model.QuestionId}' в вашей форме (а не 'Model.Question.ID', который скорее всего вызовет исключение NullReferenceException) –

+0

Я также добавил модели. QuestionId - это внешний ключ в таблице Reply и я пытаюсь заполнить его идентификатором таблицы Questionmodel. – ashhad

+0

Позвольте мне сначала отредактировать и удалить все ненужные коды. –

ответ

1

Вы должны использовать метод @Html.Action для того, чтобы сделать частичный вид и запустить дочерний действие для него. @Html.Partial не вызывает никакого действия.

Таким образом, оказание зрения ребенка должно выглядеть

@Html.Action("PostReply", new XXXXX.Models.Reply{ QuestionId = Model.Question.ID }) 

и ребенок действие в контроллере не работает с атрибутом [HttpPost]. Лучше удалить его вместе с [ValidateAntiForgeryToken].

Рекомендуется использовать такие действия с атрибутом [ChildActionOnly], чтобы запретить вызывать действие в результате прямого запроса.

UPDATE: К сожалению, я думал, что вам нужно, чтобы получить некоторые данные от действия, чтобы вынести мнение, но после комментария Стивена Муеке, я понял, что вам не нужно. Так, в общем, вы должны использовать то, что Стивен предложил

@Html.Partial("PostReply", new Chemtalks.Models.Reply { QuestionId = Model.QuestionModel.ID }) 

и затем

Html.BeginForm("PostReply", "Question", new { QuestionId = Model.QuestionId }) 

или вы можете добавить скрытое поле в форму PostReply вместо параметра маршрута

@Html.HiddenFor(model => model.QuestionId) 

The подход с параметром маршрута не может работать, если вы используете неправильную перегрузку BeginForm, напримерэто один

Html.BeginForm("PostReply", "Question", FormMethod.Post, new {QuestionId = Model.QuestionId}) 
+0

Спасибо, ты решил мою проблему. :) – ashhad

+0

Но у меня есть вопрос, я удалил ValidateAntiForgeryToken и HttpPost, а также не могу использовать ChildActionOnly, потому что при создании сообщения произошла ошибка, которая гласит: «Действие« PostReply »доступно только дочерним запросом.». Сохраняется ли использование контроллера без запрета вызовов? – ashhad

+0

Я бы предпочел не публиковать дочернее действие. Вы можете создать другое действие, которое доступно снаружи, и имеет атрибуты [HttpPost], [ValidateAntiForgeryToken], и вы можете опубликовать это действие. Общая часть двух действий может быть извлечена в отдельный метод или одно действие может быть вызвано из другого. –

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