ASP MVC 3 में एक दृश्य में दो मॉडल


91

मेरे पास 2 मॉडल हैं:

public class Person
{
    public int PersonID { get; set; }
    public string PersonName { get; set; }
}
public class Order
{
    public int OrderID { get; set; }
    public int TotalSum { get; set; }
}

मैं SINGLE दृश्य में BOTH कक्षाओं की वस्तुओं को संपादित करना चाहता हूं, इसलिए मुझे कुछ इस तरह की आवश्यकता है:

@model _try2models.Models.Person
@model _try2models.Models.Order

@using(Html.BeginForm())
{
    @Html.EditorFor(x => x.PersonID)
    @Html.EditorFor(x => x.PersonName)
    @Html.EditorFor(x=>x.OrderID)
    @Html.EditorFor(x => x.TotalSum)
}

यह, निश्चित रूप से, काम नहीं करता है: केवल एक 'मॉडल' स्टेटमेंट को .cshml फ़ाइल में अनुमति दी जाती है। हो सकता है कुछ वर्कअराउंड हो?


1
क्या मेरा जवाब आपकी मदद करता है?
एंड्रयू

मैंने ViewBagप्रत्येक व्यक्ति को मेरे लिए काम करते हुए देखा, इसके लिए कई विकल्पों को जानने के लिए जाँच की , एक दृश्य मॉडल या आंशिक दृश्य बनाने के बजाय मेरे लिए बहुत कम समय बचाया
shaijut

जवाबों:


118

एक पेरेंट व्यू मॉडल बनाएं जिसमें दोनों मॉडल हों।

public class MainPageModel{
    public Model1 Model1{get; set;}
    public Model2 Model2{get; set;}
}

इस तरह आप बहुत कम प्रयास के साथ बाद की तारीख में अतिरिक्त मॉडल जोड़ सकते हैं।


2
इस समाधान का उपयोग करते समय, कृपया ध्यान रखें कि मॉडल 1 या मॉडल 2 में परिवर्तन से आपके मेनपेजमैडल पर असर पड़ सकता है। इसके अलावा वे मुख्य रूप से देखने की जरूरत से अधिक डेटा होते हैं। यदि आपका मेनपेज उन चीजों का संयोजन है जो पहले से ही अन्य नियंत्रकों में हैं, तो RenderPartial से RenderAction पर स्विच करने से आप चीजों को बड़े करीने से अलग रख सकेंगे। कानून के कानून पर पढ़ने पर विचार करें: en.wikipedia.org/wiki/Law_of_Demeter
Fenton

1
@Andi - जैसा कि आपने ऊपर बताया था कि मैंने मॉडल बनाया है। लेकिन जब मैं नियंत्रक पर राइट क्लिक करता हूं और क्रूड नियंत्रक बनाने की कोशिश करता हूं, तो यह काम नहीं कर रहा है? कोई सुझाव? उपरोक्त मॉडल के लिए मैं स्वचालित दृश्य के साथ क्रूड नियंत्रक कैसे बना सकता हूं?
NoviceMe

2
इस समस्या को हल करने के लिए मैंने जो भी दृष्टिकोण देखे हैं, उनमें से यह मेरे लिए सबसे अच्छा काम है। यह अब तक का सबसे सरल उपाय है जो काम करता है।
सियारन गलाघेर

4
जब आप अपने आप से पूछते हैं, "इससे पहले मैंने ऐसा क्यों नहीं सोचा?" महान समाधान
राफेल AMS

1
@ और मैं नियंत्रक में संबंधित मॉडल के तरीकों को कैसे उजागर करूंगा?
Volatil3

53

टपल का उपयोग करने के लिए आपको निम्नलिखित करने की आवश्यकता है, दृश्य में मॉडल को निम्न में बदलें:

@model Tuple<Person,Order>

@html विधियों का उपयोग करने के लिए आपको निम्नलिखित कार्य करने होंगे:

@Html.DisplayNameFor(tuple => tuple.Item1.PersonId)

या

@Html.ActionLink("Edit", "Edit", new { id=Model.Item1.Id }) |

आइटम 1 टपल विधि में पारित पहले पैरामीटर को इंगित करता है और आप दूसरे मॉडल और इतने पर एक्सेस करने के लिए आइटम 2 का उपयोग कर सकते हैं।

अपने नियंत्रक में आपको टुपल का एक प्रकार बनाने की जरूरत है और फिर इसे देखने के लिए पास करें:

    public ActionResult Details(int id = 0)
    {
        Person person = db.Persons.Find(id);
        if (person == null)
        {
            return HttpNotFound();
        }
        var tuple = new Tuple<Person, Order>(person,new Order());

        return View(tuple);
    }

एक अन्य उदाहरण: एक दृश्य में कई मॉडल


1
Tupleइस मामले में कभी भी उपयोग करें - ओपी डेटा को संपादित करना चाहता है, और Tupleइसका कोई डिफॉल्ट कंस्ट्रक्टर नहीं है, इसलिए फॉर्म जमा होने पर मॉडल बाध्य नहीं किया जा सकता है

नेवर से नेवर। यहां थोड़ा मजबूत है।
जॉनी

47

एक अन्य विकल्प जिसमें कस्टम मॉडल बनाने की आवश्यकता नहीं है वह है टुपल <> का उपयोग करना ।

@model Tuple<Person,Order>

यह एक नया वर्ग बनाने के रूप में साफ नहीं है जिसमें एंडी के उत्तर के अनुसार दोनों शामिल हैं, लेकिन यह व्यवहार्य है।


mvc 3 में यह त्रुटि देता है कि एक फ़ाइल में केवल एक 'मॉडल' स्टेटमेंट की अनुमति है। किसी भी विचार यह कैसे हल करने के लिए?
जिब्बो

1
@ GibboK - मैं इसे एमवीसी 3 में ठीक उपयोग कर रहा हूं। सुनिश्चित करें कि आपके पास दो अलग @modelलाइनें नहीं हैं ?
बोबसन

3
आप प्रत्येक मॉडल के गुण प्राप्त कर सकते हैं: @Model.Item1.Propertyऔर उसके @Model.Item2.Propertyलिए Personऔर Orderक्रमशः
user2019515

1
मैंने अपने View में Tuple का उपयोग किया है। लेकिन, मैं अपने नियंत्रक में मॉडल मान प्राप्त करने में सक्षम नहीं हो सकता। लेकिन, जब मैंने @Andi के रूप में मूल दृश्य मॉडल का उपयोग करने की सिफारिश की, तो मुझे अपने नियंत्रक में मॉडल मान मिला।
नरेन

1
@StephenMuecke - हम्म। मैंने कभी इस पर विचार नहीं किया, लेकिन आप सही हैं। एक और कारण है कि एंड्रयू का जवाब बेहतर सामान्य उद्देश्य है। जब आप एक हल्के वजन विकल्प (इस तरह) के साथ जाने के लिए, आप है कार्यक्षमता छोड़ देना।
बोबसन

10

यदि आप बहुत सपाट मॉडल रखने के प्रशंसक हैं, तो केवल दृश्य का समर्थन करने के लिए, आपको इस विशेष दृश्य के लिए एक मॉडल बनाना चाहिए ...

public class EditViewModel
    public int PersonID { get; set; }
    public string PersonName { get; set; }
    public int OrderID { get; set; }
    public int TotalSum { get; set; }
}

बहुत से लोग AutoMapper का उपयोग अपने डोमेन ऑब्जेक्ट्स से अपने फ्लैट दृश्यों तक मैप करने के लिए करते हैं।

दृश्य मॉडल का विचार यह है कि यह केवल दृश्य का समर्थन करता है - और कुछ नहीं। आपके पास यह सुनिश्चित करने के लिए एक दृश्य है कि इसमें केवल वही है जो उस दृश्य के लिए आवश्यक है - उन गुणों का भार नहीं जो आप अन्य दृश्यों के लिए चाहते हैं।


5

ठीक है, हर कोई समझदारी बना रहा है और मैंने सभी टुकड़ों को ले लिया और उन्हें अपने जैसे नए लोगों की मदद करने के लिए यहां रखा, जिन्हें स्पष्टीकरण की शुरुआत की जरूरत है।

आप अपने बड़े वर्ग को @ एंड्रयूज के उत्तर के अनुसार 2 वर्ग रखते हैं।

public class teamBoards{
    public Boards Boards{get; set;}
    public Team Team{get; set;}
}

फिर अपने नियंत्रक में आप 2 मॉडल भरें। कभी-कभी आपको केवल एक भरने की आवश्यकता होती है। फिर बदले में, आप बड़े मॉडल का संदर्भ देते हैं और यह 2 को अपने साथ दृश्य में ले जाएगा।

            TeamBoards teamBoards = new TeamBoards();


        teamBoards.Boards = (from b in db.Boards
                               where b.TeamId == id
                               select b).ToList();
        teamBoards.Team = (from t in db.Teams
                              where t.TeamId == id
                          select t).FirstOrDefault();

 return View(teamBoards);

व्यू के शीर्ष पर

@model yourNamespace.Models.teamBoards

फिर अपने इनपुट्स या डिस्प्ले को देखें

 @Html.EditorFor(m => Model.Board.yourField)
 @Html.ValidationMessageFor(m => Model.Board.yourField, "", new { @class = "text-danger-yellow" })

 @Html.EditorFor(m => Model.Team.yourField)
 @Html.ValidationMessageFor(m => Model.Team.yourField, "", new { @class = "text-danger-yellow" })

तथा। । । खेत में वापसी, जब पोस्ट में आता है, बिग क्लास संदर्भ:

 public ActionResult ContactNewspaper(teamBoards teamboards)

और उस मॉडल का उपयोग करें जो लौटा है:

string yourVariable = teamboards.Team.yourField;

संभवतः कक्षा में कुछ DataAnnotation Validation सामान हैं और शायद अगर (ModelState.IsValid) को सेव / एडिट ब्लॉक के शीर्ष पर रखा जाए। । ।


4

वास्तव में एक कक्षा में दो या दो से अधिक मॉडल का उपयोग करने का एक तरीका है, उन्हें एक वर्ग में लपेटे बिना, जिसमें दोनों शामिल हैं।

एक उदाहरण मॉडल के रूप में कर्मचारी का उपयोग करना:

@model Employee

वास्तव में जैसा व्यवहार किया जाता है।

@{ var Model = ViewBag.model as Employee; }

तो View (कर्मचारी) विधि आपके मॉडल को ViewBag पर सेट कर रही है और फिर ViewEngine इसे कास्टिंग कर रहा है।

इस का मतलब है कि,

ViewBag.departments = GetListOfDepartments();
    return View(employee);

की तरह इस्तेमाल किया जा सकता है,

            @model  Employee
        @{
                var DepartmentModel = ViewBag.departments as List<Department>;
        }

अनिवार्य रूप से, आप अपने ViewBag में जो कुछ भी है उसे "मॉडल" के रूप में उपयोग कर सकते हैं, क्योंकि यह वैसे भी काम करता है। मैं यह नहीं कह रहा हूं कि यह वास्तुशिल्प रूप से आदर्श है, लेकिन यह संभव है।


3

बस इसमें सभी आवश्यक जानकारी के साथ एक एकल दृश्य मॉडल बनाएं, सामान्य रूप से मैं जो भी करता हूं वह प्रत्येक दृश्य के लिए एक मॉडल बनाता है इसलिए मैं हर दृश्य पर विशिष्ट हो सकता हूं, या तो माता-पिता मॉडल बना सकते हैं और इसे विरासत में प्राप्त कर सकते हैं। या एक मॉडल बनाएं जिसमें दोनों दृश्य शामिल हों।

व्यक्तिगत रूप से मैं उन्हें केवल एक मॉडल में शामिल करूंगा, लेकिन जिस तरह से मैं यह करता हूं वह है:

public class xViewModel
{
    public int PersonID { get; set; }
    public string PersonName { get; set; }
    public int OrderID { get; set; }
    public int TotalSum { get; set; }
}

@model project.Models.Home.xViewModel

@using(Html.BeginForm())
{
    @Html.EditorFor(x => x.PersonID)
    @Html.EditorFor(x => x.PersonName)
    @Html.EditorFor(x => x.OrderID)
    @Html.EditorFor(x => x.TotalSum)
}

1

आप प्रस्तुति पैटर्न http://martinfowler.com/eaaDev/PresentationModel.html का उपयोग कर सकते हैं

इस प्रस्तुति "दृश्य" मॉडल में व्यक्ति और आदेश दोनों शामिल हो सकते हैं, यह नया
वर्ग मॉडल हो सकता है जो आपके दृश्य संदर्भ हैं।


1
प्रस्तुति मॉडल में वास्तव में आवश्यक डेटा होना चाहिए, जो एक व्यक्ति और एक ऑर्डर से उत्पन्न हो सकता है। इसमें वास्तव में व्यक्ति या आदेश डोमेन ऑब्जेक्ट नहीं होना चाहिए। दृश्य अंतर्निहित डोमेन से डिस्प्ले को डिकूप करता है।
फेंटन

0

एक और तरीका है जिसके बारे में कभी बात नहीं की जाती है, MSSQL में एक दृश्य बनाएं जिसमें उन सभी डेटा हैं जिन्हें आप प्रस्तुत करना चाहते हैं। इसके बाद LINQ to SQL या जो भी इसे मैप करना है उसका उपयोग करें। अपने नियंत्रक में इसे दृश्य पर लौटाएं। किया हुआ।


0

यदि आप एक दृश्य पर दो मॉडल की घोषणा नहीं कर सकते हैं, उपयोग करने की कोशिश Html.Action("Person", "[YourController]")और Html.Action("Order", "[YourController]")

सौभाग्य।


यह क्या करता है?
जॉनी

0

Asp.net में एक दृश्य मॉडल के अलावा आप कई आंशिक दृश्य भी बना सकते हैं और उदाहरण के लिए, प्रत्येक दृश्य के लिए अलग-अलग मॉडल दृश्य असाइन कर सकते हैं:

   @{
        Layout = null;
    }

    @model Person;

    <input type="text" asp-for="PersonID" />
    <input type="text" asp-for="PersonName" />

तब ऑर्डर मॉडल के लिए एक और आंशिक दृश्य मॉडल

    @{
        Layout = null;
     }

    @model Order;

    <input type="text" asp-for="OrderID" />
    <input type="text" asp-for="TotalSum" />

तब आपके मुख्य दृश्य में दोनों आंशिक दृश्य लोड होते हैं

<partial name="PersonPartialView" />
<partial name="OrderPartialView" />

-1

मुझे आशा है कि आपको यह उपयोगी लगेगा !!

मैं इस तरह से कार्य के लिए प्रोजेक्ट और मॉडल के लिए ViewBag का उपयोग करता हूं, इसलिए मैं एक दृश्य में दो मॉडल का उपयोग कर रहा हूं और नियंत्रक में मैंने व्यूबैग के मूल्य या डेटा को परिभाषित किया है

List<tblproject> Plist = new List<tblproject>();
            Plist = ps.getmanagerproject(c, id);

            ViewBag.projectList = Plist.Select(x => new SelectListItem
            {
                Value = x.ProjectId.ToString(),
                Text = x.Title
            });

और देखने में tbltask और प्रोजेक्टलिस्ट मेरे दो अलग-अलग मॉडल हैं

@ {

IEnumerable<SelectListItem> plist = ViewBag.projectList;

} @ मोडेल लिस्ट

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.