2014-05-13 8 views
6

मैं अपने व्यू से नियंत्रक को वापस एक फॉर्म HttpPost के माध्यम से एक व्यूमोडेल पास कर रहा हूं। हालांकि, लौटाए गए मूल्य हमेशा शून्य होते हैं।एमवीसी व्यू देखें मॉडेल एचटीपीपोस्ट रिटर्न वैल्यू हमेशा शून्य

ViewModel

public class vmCompanyAddress 
{ 
    public StatelyTechAdmin.Models.Company Company { get; set; } 
    public StatelyTechAdmin.Models.CompanyAddress Address { get; set; } 

    public SelectList Counties { get; set; } 
} 

कंपनी क्लास मॉडल

public class Company 
{ 
    [Key] 
    public virtual long CompanyId { get; set; } 

    [Required] 
    [Display(Name = "Company Name")] 
    public virtual string Name { get; set; } 

    public virtual DateTime CreatedDate { get; set; } 

    public virtual IEnumerable<CompanyAddress> CompanyAddresses { get; set; } 
} 

CompanyAddress क्लास मॉडल

public class CompanyAddress 
{ 
    [Key] 
    public virtual long CompanyAddressId { get; set; } 

    [Required] 
    public virtual long CompanyId { get; set; } 

    [ForeignKey("CompanyId")] 
    public virtual Company Company { get; set; } 

    [Required] 
    public virtual int CopmanyAddressTypeId { get; set; } 

    [ForeignKey("CopmanyAddressTypeId")] 
    public virtual CompanyAddressType CompanyAddressType { get; set; } 

    [Display(Name = "Address 1")] 
    public virtual string Address1 { get; set; } 

    [Display(Name = "Address 2")] 
    public virtual string Address2 {get; set; } 

    [Display(Name = "Town")] 
    public virtual string Town { get; set; } 

    [Display(Name = "City")] 
    public virtual string City { get; set; } 

    [Required] 
    public virtual long CountyId { get; set; } 

    [ForeignKey("CountyId")] 
    [Display(Name = "County")] 
    public virtual County County { get; set; } 

    [Required] 
    [Display(Name = "Postal Code")] 
    public virtual string PostalCode { get; set; } 

    public virtual DateTime CreatedDate { get; set; } 
} 

नियंत्रक (मिल):

// GET: /Company/Create 
    public ActionResult Create() 
    { 
     vmCompanyAddress vm = new vmCompanyAddress(); 
     vm.Counties = new SelectList(db.County, "CountyId", "Name", -1); 
     //vm.Address = new CompanyAddress(); 
     //vm.Company = new Company(); 

     return View(vm); 
    } 

नियंत्रक (पोस्ट):

[HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult Create(vmCompanyAddress company) 
    { 
     if (ModelState.IsValid) 
     { 
      db.Companies.Add(company.Company); 

      //Amend Address Company & Address Type before save to DB 
      company.Address.CompanyId = company.Company.CompanyId; 
      company.Address.CopmanyAddressTypeId = 1; 

      db.CompanyAddress.Add(company.Address); 

      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 

     return View(company); 
    } 

देखें (बनाने)

@model StatelyTechAdmin.ViewModels.vmCompanyAddress 

@{ 
    ViewBag.Title = "Create"; 
} 

<h2>Create</h2> 

@using (Html.BeginForm()) { 
    @Html.AntiForgeryToken() 
    @Html.ValidationSummary(true) 

    <fieldset> 
     <legend>Company</legend> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Company.Name) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Company.Name) 
      @Html.ValidationMessageFor(model => model.Company.Name) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Company.CreatedDate) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Company.CreatedDate) 
      @Html.ValidationMessageFor(model => model.Company.CreatedDate) 
     </div> 


     @* Invoice Address *@ 
     <div class="editor-label"> 
      @Html.LabelFor(model => model.Address.Address1) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Address.Address1) 
      @Html.ValidationMessageFor(model => model.Address.Address1) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Address.Address2) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Address.Address2) 
      @Html.ValidationMessageFor(model => model.Address.Address2) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Address.Town) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Address.Town) 
      @Html.ValidationMessageFor(model => model.Address.Town) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Address.City) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Address.City) 
      @Html.ValidationMessageFor(model => model.Address.City) 
     </div> 

     @*<div class="editor-label"> 
      @Html.LabelFor(model => model.Address.County) 
     </div> 
     <div class="editor-field"> 
      @Html.DropDownListFor(model => model.Address.CountyId, Model.Counties) 
     </div>*@ 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Address.PostalCode) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Address.PostalCode) 
      @Html.ValidationMessageFor(model => model.Address.PostalCode) 
     </div> 

     <p> 
      <input type="submit" value="Create" /> 
     </p> 
    </fieldset> 
} 

किसी के बारे में कोई सलाह प्रदान करते हैं कृपया मेरे रिटर्न व्यू मॉडेल मान क्यों नल होते हैं जब सभी फ़ील्ड आबादी वाले होते हैं?

मैंने नेटवर्क रिकॉर्ड सुविधा का उपयोग करके Google क्रोम ब्राउज़र में चेक किया है और सभी मान JSON प्रारूप में वापस पोस्ट किए गए हैं।

बहुत धन्यवाद।

------------ संपादित ---------------

यहाँ मैं क्या गूगल क्रोम नेटवर्क से देख सकते हैं का हिस्सा है मॉनिटर

Company.Name:ABC123 Company.CreatedDate: 2014/05/13 00:00:00 ....

तो यह निश्चित रूप से वापस आ जा रहा है।

+0

काफी अजीब बात है, किसी को वापस "Company.Name" पोस्टिंग के साथ एक समान मुद्दा पड़ा है। Funsies के लिए, उस फ़ील्ड को हटाने का प्रयास करें और देखें कि क्या यह अभी भी सब कुछ वापस पोस्ट करता है। http://stackoverflow.com/questions/780026/asp-net-mvc-model-binding-returning-null-values ​​ –

+1

CompanyAddressTypeId गलत वर्तनी है। साथ ही, इस तरह अपने फॉर्म को परिभाषित करने का प्रयास करें - Html.BeginForm ("yourControllerNameHere", "Create", FormMethod.Post) – JB06

+0

धन्यवाद @ErikElkins हालांकि, मेरे व्यू से Company.Name को हटाकर कोई फर्क नहीं पड़ता। सबकुछ अभी भी न्यूल के रूप में वापस पोस्ट करता है। – RobHurd

उत्तर

11

मैं आपकी समस्या को पुन: उत्पन्न करने में सक्षम था और उलझन में था क्योंकि मुझे पता है कि डिफ़ॉल्ट एमवीसी मॉडल बाइंडर जटिल प्रकारों को समझता है। मैंने अधिकांश कोड को हटा दिया और बस कंपनी ऑब्जेक्ट के साथ ऐसा करने की कोशिश की, जो अभी भी असफल रहा।मैं तो देखा कि vmCompanyAddress में उस वर्ग के नाम भी संपत्ति का नाम था:

public class vmCompanyAddress 
{ 
    public StatelyTechAdmin.Models.Company Company { get; set; } 

मैं कुछ वर्ग के नाम से अलग करने के लिए संपत्ति का नाम बदल दिया है और यह काम करना शुरू किया:

public class vmCompanyAddress 
{ 
    public StatelyTechAdmin.Models.Company TheCompany { get; set; } 
+3

बिल्कुल जगह पर! बहुत धन्यवाद, वास्तव में आप मेरे लिए यह देखने की सराहना करते हैं। मैं निश्चित रूप से एक ही गलती नहीं करूँगा। – RobHurd

+2

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

2

इसने स्वयं की कोशिश नहीं की है लेकिन बहुत समय पहले इसी तरह के मुद्दों को हल किया गया था कि मैंने कस्टम मॉडलबिन्डर के साथ हल किया है: जिसे मैं अनुशंसा नहीं करता हूं।

मुझे लगता है कि आपका डेटा इस तरह दिखता नहीं है: {Company: {...}, पता: {...}}?

मुझे लगता है कि समाधान एमवीसी टेम्पलेट्स और EditorFor() का उपयोग कर डेटा की संरचना को समझने के लिए है। एक अच्छे उदाहरण के लिए http://lostechies.com/jimmybogard/2011/09/07/building-forms-for-deep-view-model-graphs-in-asp-net-mvc/ देखें!

+0

धन्यवाद। @MatthewAtCriticalCogni सिर पर कील मारा। मेरी व्यू मॉडेल संपत्ति को मेरी कक्षा के समान नाम दिया गया था, इस प्रकार यह असफल हो गया। – RobHurd

10

हमें आज भी यही समस्या थी। इस प्रश्न में स्वीकृत उत्तर वास्तविक समस्या के लिए केवल एक गंदे कामकाज है।

क्लासनाम और प्रॉपर्टीनाम एक फॉर्म मॉडल में समान हो सकता है, मॉडल बाइंडर में कोई सीमा नहीं है। सीमा आपके नियंत्रक में कार्रवाई का पैरामीटर है। आपको अपने फॉर्म मॉडल में जटिल प्रकार वाले प्रॉपर्टी जैसे पैरामीटर का नाम नहीं देना चाहिए। कारण बाइंडर आपके नियंत्रक में इस पैरामीटर में company के HTTP पोस्ट फॉर्म मान को बाध्य करने का प्रयास करेगा। यह आपके लिए काम नहीं करेगा, क्योंकि बाइंडर Company के मानों को बांधने का प्रयास करता है CompanyAddress प्रकार पर टाइप करें।

अपनी समस्या को ठीक करने के लिए, आपको बस पैरामीटर companycompanyAddressModel - या जो भी आपके मॉडल वर्ग में कोई संपत्ति नहीं है, का नाम बदलना होगा।

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Create(CompanyAddress company) 

बदलने के लिए:

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Create(CompanyAddress companyAddressModel) 

अधिक जानकारी के लिए यहाँ देखें मॉडल बंधन के बारे में: http://aspnetmvc.readthedocs.org/projects/mvc/en/latest/models/model-binding.html

MVC नाम द्वारा मापदंडों कार्रवाई करने के लिए अनुरोध डेटा बाध्य करने की कोशिश करेंगे। एमवीसी पैरामीटर नाम और इसके सार्वजनिक सेटटेबल गुणों के नाम का उपयोग करके प्रत्येक पैरामीटर के मानों की तलाश करेगा। [...] मार्ग मूल्यों के अतिरिक्त एमवीसी अनुरोध के विभिन्न हिस्सों से डेटा बाध्य करेगा और यह एक सेट ऑर्डर में ऐसा करता है।

  • फार्म को महत्व देता है: नीचे कि मॉडल के माध्यम से उन्हें बाध्यकारी दिखता क्रम में डेटा स्रोतों की एक सूची है ये प्रपत्र मूल्यों POST विधि का उपयोग कर HTTP अनुरोध में जाना जाता है।
  • मार्ग मान: रूटिंग द्वारा प्रदान किए गए मार्ग मानों का सेट।
  • क्वेरी स्ट्रिंग्स: यूआरआई का क्वेरी स्ट्रिंग हिस्सा।

ASP.NET WebAPI documentation से एक अच्छा उदाहरण है, जो उसी तकनीक का उपयोग कर रहा है:

HttpResponseMessage Put(int id, Product item) { ... } 

यहाँ Product की Id संपत्ति नियंत्रक में id पैरामीटर के लिए मैप किया गया है। जो काम करेगा, कार्रवाई में कारण मॉडल वर्ग में समान आदिम डेटा प्रकार का उपयोग किया जाता है।

2

सुनिश्चित करें कि आपका व्यूमोडेल गुणों को उजागर कर रहा है न केवल फ़ील्ड।

यह काम करता है:

public DAL.Models.Account acct {get;set;} 

यह नहीं करता है:

public DAL.Models.Account acct; 
संबंधित मुद्दे