2016-03-22 13 views
0

Ich habe eine Ansicht mit dem Namen 'Details', die eine Teilansicht 'PostReply' enthält. Ich versuche, eine ID aus der Detailansicht an die PostReply-Controller-Aktion zu übergeben.Übergeben eines ID-Wertes an die Teilansicht

Ich habe dies in der Detailansicht versucht, aber es drückt Nullwert der ID.

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

Dann habe ich versucht, einen ID-Wert zu Begin in Antworten (Teilansicht) wie folgt ergänzt:

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

Das funktioniert auch nicht. Wie kann ich ID-Wert von Details zu PostReply bekommen? Danke im Voraus.

Details anzeigen:

@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()) 

Antworten (Teilansicht):

@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" /> 
} 

Einzelheiten & Antworten Controller:

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 Modell:

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

Sie haben die Modelle nicht gezeigt, aber 'neue XXXXX.Models.Reply {QuestionID = Model.Question.ID})' 'bedeutet Reply' eine Eigenschaft enthält namens' QuestionId' so Ihre Ich vermute Will '' neue {ID = Model.QuestionId} 'in Ihrem Formular (nicht' Model.Question.ID', die wahrscheinlich eine NullReferenceException werfen würde) –

+0

Ich habe auch Modelle hinzugefügt. QuestionId ist ein Fremdschlüssel in einer Tabelle Reply und ich versuche, es mit der ID der Questionmodel-Tabelle zu füllen – ashhad

+0

Lassen Sie mich zuerst alle irrelevanten Code bearbeiten und entfernen. –

Antwort

1

Sie sollten die @Html.Action Methode, um eine Teilansicht verwenden zu machen und ein Kind Aktion für sie laufen. @Html.Partial ruft keine Aktionsmethode auf.

Also, Rendering des Kindes Ansicht sollte wie folgt aussehen

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

und das Kind Aktion in der Steuerung funktioniert nicht mit dem Attribut [HttpPost]. Es ist besser, es zusammen mit [ValidateAntiForgeryToken] zu entfernen.

Es ist eine gute Praxis, solche Aktionen mit dem Attribut [ChildActionOnly] zu verwenden, um das Aufrufen der Aktion als Ergebnis einer direkten Anfrage zu verbieten.

UPDATE: Sorry, ich dachte, dass Sie einige Daten aus der Aktion erhalten muss ich erkannte die Ansicht, aber nach Stephen Muecke Kommentar zu machen, dass Sie das nicht brauchen. Also, im Allgemeinen sollten Sie verwenden, was Stephen vorgeschlagen

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

und dann

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

oder Sie können ein verstecktes Feld zu Ihrer Antworten Form anstelle der Routenparameter

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

Die hinzufügen Ansatz mit dem Parameter Route konnte nicht funktionieren, wenn Sie eine falsche BeginForm Überladung verwenden zdieses

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

Danke, du hast mein Problem gelöst. :) – ashhad

+0

Aber ich habe eine Frage, ich habe ValidateAntiForgeryToken und HttpPost gelöscht und kann auch nicht ChildActionOnly verwenden, weil beim Erstellen eines Beitrags ist ein Fehler aufgetreten, der sagt, dass die Aktion 'PostReply' nur durch eine untergeordnete Anfrage zugänglich ist. '. Ist es sicher, Controller zu verwenden, ohne Anrufe zu verbieten? – ashhad

+0

Ich würde es vorziehen, nicht auf die Kinderaktion zu posten. Sie könnten eine andere Aktion erstellen, die von außen verfügbar ist und über die Attribute [HttpPost], [ValidateAntiForgeryToken] verfügt, und Sie könnten diese Aktion posten. Der gemeinsame Teil von zwei Aktionen könnte in eine separate Methode extrahiert werden, oder eine Aktion könnte von einer anderen aufgerufen werden. –

Verwandte Themen