2015-01-20 15 views
17

मैं अपना पहला एएसपी.नेट एमवीसी प्रोजेक्ट शुरू कर रहा हूं, इसलिए मेरे पास एक साधारण सवाल है। मैं कोड निम्नलिखित है:रेडियो बटन के एएसपी.नेट एमवीसी 5 समूह

foreach(var question in Model.GeneralQuestions) 
{ 
    <div class = "well"> 
     <h3> 
      <strong>@question.QuestionString</strong> 
     </h3> 
     @foreach (var answer in question.PossibleAnswers) 
     { 
      @Html.RadioButtonFor(model => question.QuestionString, answer.Answer) 
      @Html.Label(answer.Answer) 
      <br /> 
     } 
    </div> 
} 

Model.GeneralQuestions में सभी प्रश्न, अद्वितीय हैं तो रेडियो बटन (रेडियो बटनों में से प्रत्येक प्रश्न के एक समूह के लिए) नाम विशेषता द्वारा समूहों में विभाजित किया जाना चाहिए। लेकिन यह कोड केवल एक समूह का उत्पादन करता है, इसलिए जब मैं दूसरे प्रश्न का उत्तर देता हूं तो पहले किसी को अचयनित कर दिया जाता है। मुझे बदलने की क्या ज़रूरत है?

संपादित
मेरे मॉडल लगता है:

public class StudentViewModel 
{ 
    public Student Student { get; set; } 
    public List<Question> GeneralQuestions { get; set; } 
    public List<SubjectQuestions> SubjectQuestions { get; set; } 
} 
public class Student 
{ 
    public int StudentID { get; set; } 
    public string Index { get; set; } 
    public string Name { get; set; } 
    public string Surname { get; set; } 

    public virtual ICollection<Subject> Subjects { get; set; } 
} 
public class Question 
{ 
    public int QuestionID { get; set; } 
    public string QuestionString { get; set; } 
    public bool IsAssociatedWithSubject { get; set; } 

    public virtual ICollection<PossibleAnswer> PossibleAnswers { get; set; } 
    public virtual ICollection<Results> Results { get; set; } 
} 
public class SubjectQuestions 
{ 
    public Subject Subject { get; set; } 
    public List<Question> Questions { get; set; } 
} 
public class Results 
{ 
    public int ResultsID { get; set; } 
    public int QuestionID { get; set; } 
    public int? SubjectID { get; set; } 
    public int PossibleAnswerID { get; set; } 

    public virtual Question Question { get; set; } 
    public virtual PossibleAnswer PossibleAnswer { get; set; } 
    public virtual Subject Subject { get; set; } 
} 

StudentViewModel का एक उदाहरण में मैं एक छात्र और सभी सवालों कि वह (दोनों सामान्य और विषयों वह अध्ययन कर रही है करने के लिए संबंधित) और पास में उत्तर देना चाहिए बचाने के इसे देखने के लिए। ध्यान में मैंने सभी प्रश्नों को एक ही रूप में रखा है और वे सभी प्रकार के रेडियो हैं। तो, क्या कोई मुझे रेडियो बटनों के समूहकरण और इस फ़ॉर्म को सही तरीके से पोस्ट करने में मदद कर सकता है?

+1

बस एक त्वरित प्रतिक्रिया लेकिन क्या आपने यह लेख देखा है? http://stackoverflow.com/a/22178728/1765853 – macoms01

+0

तब तक जब तक 'प्रश्नस्ट्रिंग' अद्वितीय नहीं है, यह प्रत्येक प्रश्न के लिए एक समूह बनाना चाहिए, हालांकि 'प्रश्नस्ट्रिंग' के लिए बाध्यकारी लग रहा है - क्या आपको कुछ ऐसा बाध्यकारी नहीं होना चाहिए 'SelectedAnswer'? क्या आप कुछ एचटीएमएल दिखा सकते हैं जो –

+0

उत्पन्न कर रहा है आपका बाहरी पाश भी 'लूप' होना चाहिए ताकि आपके नियंत्रण इंडेक्सर्स के साथ नाम की संपत्ति पोस्ट की गई हो। –

उत्तर

23

नकल id के (अवैध एचटीएमएल) पैदा करने सहित अपने कोड के साथ समस्याओं का एक नंबर, name गुण नकल (जो कारण है कि आप केवल एक समूह बना रहे हैं, लेकिन अधिक महत्वपूर्ण बात यह के लिए बाध्य करने से रोकेंगी पैदा कर रहे हैं जब आप वापस पोस्ट करते हैं तो मॉडल) और आप वास्तव में किसी वैध संपत्ति के लिए बाध्यकारी नहीं हैं।

आपको for लूप (या EditorTemplate का उपयोग करके) को प्रदर्शित करने और रेडियो बटन को संपादित करने और उत्पन्न करने के लिए दृश्य मॉडल बनाने की आवश्यकता होगी ताकि वे इंडेक्सर्स के साथ सही ढंग से नामित हों।

मॉडल देखें

public class QuestionVM 
{ 
    public int ID { get; set; } // for binding 
    public string Text { get; set; } 
    [Required] 
    public int? SelectedAnswer { get; set; } // for binding 
    public IEnumerable<AnswerVM> PossibleAnswers { get; set; } 
} 

public class SubjectVM 
{ 
    public int? ID { get; set; } 
    [DisplayFormat(NullDisplayText = "General")] 
    public string Name { get; set; } 
    public List<QuestionVM> Questions { get; set; } 
} 

public class AnswerVM 
{ 
    public int ID { get; set; } 
    public string Text { get; set; } 
} 

public class StudentVM 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
    // plus any other properties of student that you want to display in the view 
    public List<SubjectVM> Subjects { get; set; } 
} 

देखें

@model YourAssembly.StudentVM 
@using(Html.BeginForm()) 
{ 
    @Html.HiddenFor(m => m.ID) 
    @Html.DisplayFor(m => m.Name) 
    for(int i = 0; i < Model.Subjects.Count; i++) 
    { 
    @Html.HiddenFor(m => m.Subjects[i].ID) 
    @Html.DisplayFor(m => m.Subjects[i].Name) // will display "General" if no name 
    for (int j = 0; j < Model.Subjects[i].Questions.Count; j++) 
    { 
     @Html.HiddenFor(m => m.Subjects[i].Questions[j].ID) 
     @Html.DisplayFor(m => m.Subjects[i].Questions[j].Text) 
     foreach(var answer in Model.Subjects[i].Questions[j].PossibleAnswers) 
     { 
     <div> 
      @Html.RadioButtonFor(m => m.Subjects[i].Questions[j].SelectedAnswer, answer.ID, new { id = answer.ID}) 
      <label for="@answer.ID">@answer.Text</label> 
     </div> 
     } 
     @Html.ValidationMessageFor(m => m.Subjects[i].Questions[j].SelectedAnswer) 
    } 
    } 
    <input type="submit" value="save" /> 
} 

नियंत्रक

public ActionResult Edit(int ID) 
{ 
    StudentVM model = new StudentVM(); 
    // populate your view model with values from the database 
    return View(model); 
} 

[HttpPost] 
public ActionResult Edit(StudentVM model) 
{ 
    // save and redirect 
} 

नोट मैं (उदाहरण के लिए डेटाबेस संरचना अपने मॉडल से गर्भित द्वारा एक छोटे से उलझन में हूँ तुम क्यों की क्या ज़रूरत है Question और SubjectQuestion के लिए अलग मॉडल जब nullSubjectID के लिए मूल्य इसे "सामान्य" प्रश्न के रूप में पहचानता है)। मेरा सुझाव है कि आप यह सुनिश्चित करने के लिए जीईटी विधि में कुछ मूल्यों को कड़ी-कोड करके शुरू करें कि यह कैसे काम करता है और वापस पोस्ट करता है।

StudentVM model = new StudentVM(); 
model.ID = 1; 
model.Name = "bambiinela"; 
model.Subjects = new List<SubjectVM>() 
{ 
    new SubjectVM() 
    { 
    Questions = new List<QuestionVM>() 
    { 
     new QuestionVM() 
     { 
     ID = 1, 
     Text = "Question 1", 
     SelectedAnswer = ?, // set this if you want to preselect an option 
     PossibleAnswers = new List<AnswerVM>() 
     { 
      new AnswerVM() 
      { 
      ID = 1, 
      Text = "Answer A" 
      }, 
      new AnswerVM() 
      { 
      ID = 1, 
      Text = "Answer B" 
      } 
     } 
     }, 
     new QuestionVM() 
     { 
     ID = 2, 
     Text = "Question 2", 
     PossibleAnswers = new List<AnswerVM>() 
     { 
      // similar to above 
     } 
     } 
    } 
    }, 
    new SubjectVM() 
    { 
    ID = 1, 
    Name = "Math", 
    Questions = new List<QuestionVM>() 
    { 
     // similar to above 
    } 
    } 
}; 

जब आप पोस्ट करते हैं, तो मॉडल प्रत्येक विषय में प्रत्येक प्रश्न के लिए चयनित उत्तर की आईडी के साथ पॉप्युलेट किया जाता है। कुछ गुणों के लिए DisplayFor() के उपयोग पर ध्यान दें। ये वापस पोस्ट नहीं करेंगे इसलिए यदि आप दृश्य वापस करते हैं तो आपको इन गुणों को दोबारा स्थापित करना होगा (उदा। ModelState मान्य नहीं है)। वैकल्पिक रूप से आप केवल पढ़ने के लिए टेक्स्टबॉक्स उत्पन्न कर सकते हैं या उन गुणों के लिए एक छिपी हुई इनपुट जोड़ सकते हैं। मैं भी आप HTML कि उत्पन्न होता है, विशेष रूप से नाम का श्रेय तरह

<input type="radio" name="Subjects[0].Questions[0].SelectedAnswer" ... 

आप कैसे संग्रह के बाद वापस

+0

धन्यवाद! सभी सलाह उपयोगी थीं और कोड सही है। अब मैंने एमवीसी के लिए मॉडल को अलग किया है और डेटाबेस में सहेजने के लिए प्रवेश करता है क्योंकि डेटाबेस में मेरे एंटरसाइट्स को एमवीसी मॉडल से थोड़ा अलग दिखना चाहिए। – bambi

+0

क्या छात्रवृत्ति ऑब्जेक्ट में प्रश्न प्रश्न, विषय नाम इत्यादि पोस्ट करने का कोई तरीका है? मुझे बस पोस्ट विधि में उत्तर दिए गए सवालों के आईडी हैं ('[एचटीपीपोस्ट] सार्वजनिक एक्शन रिसैट छात्र (छात्रवीएम मॉडल) {}'), अन्य फ़ील्ड खाली लगते हैं। – bambi

+0

जैसा कि मैंने नोट किया है, आप उन गुणों के लिए छिपी हुई इनपुट बना सकते हैं जो अतिरिक्त @ @ HTML.DisplayFor() '- उदा। '@ Html.HiddenFor (m => m.Name) 'या आप' डिस्प्लेफ़ोर 'को' @ Html.TextBoxFor (m => m.Name, new {@readonly = "readonly", @ class = "readonly से बदल सकते हैं ") 'और फिर इसे स्टाइल करने के लिए सीएसएस का उपयोग करें।हालांकि, बहुत सारे अनावश्यक छिपे हुए इनपुट बनाने से प्रदर्शन खराब हो सकता है (इसे क्लाइंट को भेजना और फिर वापस आना) और आपको ओवरपोस्टिंग हमलों के लिए खुलता है। अक्सर डेटाबेस से डेटा फिर से प्राप्त करना बेहतर होता है लेकिन केवल आप ही सर्वोत्तम विकल्प का आकलन कर सकते हैं। –

2

चाल पर अपने मॉडल के लिए बाध्य कर रहे हैं की समझ देने के लिए कुछ दिखेगा जो निरीक्षण का सुझाव एक अभिव्यक्ति का उपयोग करना है (Html.RadioButtonFor के लिए पहला पैरामीटर) जिसमें एक मान होता है जो रेडियो-बटन के प्रति समूह को बदलता है।आपके मामले में, यह प्रश्नों की सूची में एक सूचकांक होगा।

public class StudentViewModel 
{ 
    public List<Question> GeneralQuestions { get; set; } 
} 

public class Question 
{ 
    public int QuestionId { get; set; } 
    public string QuestionString { get; set; } 
    public ICollection<PossibleAnswer> PossibleAnswers { get; set; } 
    public int SelectedAnswerId { get; set; } 
} 

public class PossibleAnswer 
{ 
    public int Id { get; set; } 
    public string Answer { get; set; } 
} 
:

<label for="Q1">Q1</label> 
<br /> 
<input id="GeneralQuestions_0__SelectedAnswerId" 
    name="GeneralQuestions[0].SelectedAnswerId" type="radio" value="1" /> 
<label for="A01">A01</label> 
<br /> 
<input id="GeneralQuestions_0__SelectedAnswerId" 
    name="GeneralQuestions[0].SelectedAnswerId" type="radio" value="2" /> 
<label for="A02">A02</label> 
<br /> 
<label for="Q2">Q2</label> 
<br /> 
<input id="GeneralQuestions_1__SelectedAnswerId" 
    name="GeneralQuestions[1].SelectedAnswerId" type="radio" value="11" /> 
<label for="A11">A11</label> 
<br /> 
<input id="GeneralQuestions_1__SelectedAnswerId" 
    name="GeneralQuestions[1].SelectedAnswerId" type="radio" value="12" /> 
<label for="A12">A12</label> 
<br /> 

और पूर्णता के लिए के लिए, यहां इस्तेमाल किया मॉडल का एक कम संस्करण है:

@for (int i = 0; i < Model.GeneralQuestions.Count; i++) 
{ 
    var question = Model.GeneralQuestions[i]; 
    @Html.Label(question.QuestionString) 
    <br /> 
    foreach (var answer in question.PossibleAnswers) 
    { 
     @Html.RadioButtonFor(model => 
      Model.GeneralQuestions[i].SelectedAnswerId, answer.Id) 
     @Html.Label(answer.Answer) 
     <br /> 
    } 
} 

यह निम्न HTML पैदा करता है:

यहां कुछ नमूना कोड है

और यहां क्रिया विधि से कोड है:

return View(new StudentViewModel 
{ 
    GeneralQuestions = 
     new List<Question> 
     { 
      new Question 
      { 
       QuestionString = "Q1", 
       PossibleAnswers = 
        new[] 
        { 
         new PossibleAnswer {Id = 1, Answer = "A01"}, 
         new PossibleAnswer {Id = 2, Answer = "A02"} 
        } 
      }, 
      new Question 
      { 
       QuestionString = "Q2", 
       PossibleAnswers = 
        new[] 
        { 
         new PossibleAnswer {Id = 11, Answer = "A11"}, 
         new PossibleAnswer {Id = 12, Answer = "A12"} 
        } 
      }, 
     } 
}); 
संबंधित मुद्दे