Question

Trying to change my view to PartialView, that I use it with tabs System, I got this error : There is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key 'REGION_ID'. at line 30 of _CreateCit.cshtml file :

@model pfebs0.Models.CITOYEN

<h2>Demandeur Info</h2>

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



        // some code removed (HTML tag)

        <div class="form-group">
            <label for="REGION_ID" >Region</label>
            @Html.DropDownList("REGION_ID", String.Empty)
            @Html.ValidationMessageFor(model => model.REGION_ID)
        </div>

// some other input tag 
        <br />
            <button type="submit" class="btn btn-default">Valider</button>&nbsp; &nbsp;
            <button type="reset" class="btn btn-default">Annuler</button>&nbsp; &nbsp;
    </div>
}

And this my index.cshtml file`:

    @{
    ViewBag.Title = "Creation D'un nouveau Demande";
}

<ul class="nav nav-tabs" id="myTab">
  <li class="active"><a href="#tab1">Add user tab</a></li>
  <li><a href="#tab2">add request tab</a></li>

</ul>
<div class="tab-content">
     <div id="tab1" class="tab-pane active">
        @Html.Partial("_CreateCit", ViewData)
     </div>

    <div id="tab2" class="tab-pane">
         @Html.Partial("_CreateDM")
    </div>
</div>



@section Scripts {
    // script Section removed
}

her's my Controller code :

public ActionResult CreateCit()
    {
        ViewData["REGION_ID"] = new SelectList(db.REGION, "REGION_ID", "NOM");
        return PartialView("_CreateCit");
    }

    //
    // POST: /Citoyen/Create

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult CreateCit(CITOYEN citoyen)
    {
        if (ModelState.IsValid)
        {
            db.CITOYEN.Add(citoyen);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        ViewBag.REGION_ID = new SelectList(db.REGION, "REGION_ID", "NOM", citoyen.REGION_ID);
        return PartialView(citoyen);
    }

The same code work with standard view, I just changed return View to return PartialView(Viewname) and I edited the cshtml file. I think I missed something !!

Was it helpful?

Solution

The @Html.Partial just renders the partial view and does not call the controller action. It just takes the partial view code, without reaching the controller (set a break point in the action and test this). The ViewData will not contain the data that you think it will. You need to use @Html.Action:

<div id="tab1" class="tab-pane active">
    @Html.Action("CreateCit")
 </div>

<div id="tab2" class="tab-pane"> 
     @Html.Action("CreateDM")
</div>

Alternatively, try explicitly adding the data in the ViewData object, before calling @Html.Partial:

<div id="tab1" class="tab-pane active">
    @{
          ViewData["REGION_ID_DDL"] = ViewData["REGION_ID"]
    }
    @Html.Partial("_CreateCit", ViewData)
 </div>

Edit: To address your comment about the success message: there are several things you can do to display a success message. My personal favorite is to create a ResultModel:

public class ResultModel
{
     public string Message { get; set; }
     public ResultType TypeOfResult { get; set; }
}

public Enum TypeOfResult 
{
     Error,
     Success
}

Create a partial view which accepts a ResultModel and displays the message:

@model YourNamespace.Models.ResultModel

<p>Sort du resultat: @Model.TypeOfResult</p>
<p>Message: @Model.Message</p>

You would then just call it like this:

 if (ModelState.IsValid)
 {
     db.CITOYEN.Add(citoyen);
     db.SaveChanges();

     ResultModel resultModel = new ResultModel();
     resultModel.TypeOfResult = TypeOfResult.Success;
     //my french is a bit rusty but the result from Google Translate sounds good enough
     resultModel.Message = "Citoyen ajouté avec succès.";


     return PartialView("_ResultSummary", resultModel);
 }

Of course, this can be used to trace out errors as well. You could add a try-catch around the db.SaveChanges(); call and set the success type/message in the try block and the error type/message in the catch block.

Another advantage of this method is that the ResultModel object can also be sent as a JSON string, in case you want to display a JavaScript "alert" or even a custom pop-up.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top