سؤال

I am having 2 functionalities Load and Edit. The records are loaded in the WebGrid and for edit i'm using popup. But for both functions i'm using the same Model. This is where i'm getting error.

When the records are loaded it works fine, when i use edit it works fine, but when i try to save the edits and return the model i'm getting error.

//MainView

@model AdhiaRecruitment.Models.CandidateDetailsModel
@{
    ViewBag.Title = "CandidateDetails";
    Layout = "~/Views/Shared/_Layout.cshtml";

    <style type="text/css">
        .grid
        {
            width: 100%;
        }
    </style>
}
<h2>
    CandidateDetails</h2>
<div style="padding: 7px 0;">
    <input type="button" value="Add New Product" onclick="OpenCreatePopup()" />
</div>
<div style="width: 100%;">
    @{
        string template = string.Format("<text><img src='/img/edit.png' title='Edit' onclick='EditProduct({0})' /><img src='/img/delete.png' title='Delete' onclick='DeleteProduct({0})' /></text>", Model.CDId);

        WebGrid grid = new WebGrid(Model.LoadAllCandidateDetails());
        @grid.GetHtml(
         tableStyle: "grid",
         fillEmptyRows: false,
         headerStyle: "gvHeading",
         alternatingRowStyle: "gvAlternateRow",
         rowStyle: "gvRow",
         footerStyle: "gvFooter",

         mode: WebGridPagerModes.All,
         firstText: "<< First",
         previousText: "< Prev",
         nextText: "Next >",
         lastText: "Last >>",
         columns: new[] {
         grid.Column("CDId", "ID"), 
         grid.Column("Name", "Name"),   
         grid.Column("Gender", "Gender"),                        
         grid.Column("", header: "Actions", canSort:false,
            format: @<text>
        @Html.Raw("<img src='/Images/edit-icon.png' alt='Edit' title='Edit' onclick='EditProduct(" + item.CDId + ")'  />")
        @Html.Raw("<img src='/Images/delete-icon.png' alt='Delete' title='Delete' onclick='DeleteProduct(" + item.CDId + ")'  />")
        </text>
        )    

     })    
    }
</div>
<div id="DivToAppendPartialView">
</div>
<script type="text/javascript">

        var ph = $("#DivToAppendPartialView");
        ph.dialog({
            modal: true,
            width: 560,
            height: 560,
            title: "Edit Candidate",
            resizable: false,
            autoOpen: false
        });

    function EditProduct(cid) {

        ph.load("/CandidateDetails/EditCandidateDetails?candidateid=" + cid, function () {
            ph.dialog('open');

        });
    }
</script>

//Edit View

 @model AdhiaRecruitment.Models.CandidateDetailsModel

    @using (Html.BeginForm())
    {

        @Html.ValidationSummary(true)
        <fieldset>
            <legend>CandidateDetailsModel</legend>
            <div class="editor-label">
             @*  # @Html.DisplayFor(model => model.CDId)*@
               @Html.EditorFor(model => model.CDId)
            </div>
            <div class="editor-label">
                @Html.LabelFor(model => model.Name)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Name)
                @Html.ValidationMessageFor(model => model.Name)
            </div>
<div class="editor-label">
            @Html.LabelFor(model => model.Gender)
        </div>
        <div class="editor-field">
            @Html.DropDownListFor(m => m.Gender, Model.GenderList(),"--Select--")
             @Html.ValidationMessageFor(x => x.Gender, "Gender field is required")
        </div>
            <p>
                <input type="submit" value="Save" />
            </p>
        </fieldset>
    }
    <div>
        @Html.ActionLink("Back to List", "Index")
    </div>

//Model

public class CandidateDetailsModel
    {

        public int CDId { get; set; }

        [Required(ErrorMessage = "Please provide name!")]
        [StringLength(50, ErrorMessage = "Name is too long!")]
        [Display(Name = "Name")]
        public string Name { get; set; }
         [Required(ErrorMessage = "Please select gender!")]
        [Display(Name = "Gender")]
        public string Gender { get; set; }

   public SelectList GenderList()
        {
            List<SelectListItem> lstGender = new List<SelectListItem>
            {
                new SelectListItem { Value = "1", Text = "Male" },
                new SelectListItem { Value = "2", Text = "Female" },
            };

            var selected = lstGender.Where(x => x.Text == Gender).First();
            Gender = selected.Value;

            return new SelectList(lstGender, "Value", "Text", Gender);
        }

  public List<CandidateDetails> LoadAllCandidateDetails()
        {
            List<CandidateDetails> lstCandidateDetails = new List<CandidateDetails>();

            CandidateServiceClient csClient = new CandidateServiceClient();
            lstCandidateDetails = csClient.LoadAllCandidateDetails();

            return lstCandidateDetails;
        }

 public int SaveCandidateDetails(CandidateDetails cdDetails)
        {
            int result = 0;

            CandidateServiceClient csClient = new CandidateServiceClient();
            result = csClient.SaveCandidateDetails(cdDetails);

            return result;
        }

//Controller

public class CandidateDetailsController : Controller
    {
        //  
        // GET: /Candidate/

        public ActionResult CandidateDetails()
        {
            return View(new CandidateDetailsModel());
        }

        [HttpGet]
        public PartialViewResult EditCandidateDetails(int candidateId)
        {
            CandidateDetailsModel cdSingle = new CandidateDetailsModel();

            CandidateDetails cdModel = cdSingle.LoadAllCandidateDetails().Where(x => x.CDId == candidateId).FirstOrDefault();

            cdSingle.CDId = cdModel.CDId;
            cdSingle.Name = cdModel.Name;
            cdSingle.Gender = cdModel.Gender;

            return PartialView(cdSingle);
        }

        [HttpPost]
        public ViewResult EditCandidateDetails(CandidateDetails cdDTO)
        {
            CandidateDetailsModel cdModel = new CandidateDetailsModel();

            CandidateDetails cdSingle = new CandidateDetails();

            cdSingle.CDId = cdDTO.CDId;
            cdSingle.Name = cdDTO.Name;
            cdSingle.Gender = cdDTO.Gender;

            cdModel.SaveCandidateDetails(cdSingle);           

            return View(cdModel);
        }

    }

After clicking save the model is loaded and when the GenderList is loading its throwing me the null error.

I'm not sure the process for MVC i have written is right. Do i have to create a separate model for Edit? If yes, For example if i have some 15 Edit functionalities in my application then i have to create 30 models??

Kindly help.

هل كانت مفيدة؟

المحلول

In your Edit Partial View you do not have a gender dropdown menu so when model binding happens on the Controller method, gender is always going to be null.

If you do not want the user to change/edit gender then you can use a hidden field to send the current gender back to the server.

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

If you want to make gender editable then you will need a dropdown menu.

@Html.DropDownListFor(model => model.Gender, Model.GenderList())

EDIT: To solve the null Gender problem just put a null check and default it like so:

Gender = Gender == null ? "male" : Gender; //Set default if null
var selected = lstGender.Where(x => x.Text == Gender).First();
            Gender = selected.Value;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top