0

While performing edit operation , During the create operation user selecting the state and city from respective dropdowns, So I am trying to get that selected State and city drop down which are binded in SQL db

Edit Get Operation Controller

public async Task<IActionResult> Edit(int? id)
        {
            StudentViewModel model = new StudentViewModel();
            StudentTables students = new StudentTables();

            ViewBag.title = "Edit Student";
            ViewBag.button = "Update";
            ViewBag.action = "Edit";
            ViewBag.States = GetState(string.Empty);
            ViewBag.City = GetCities(model.StateId);
            //ViewBag.City = model.StateId > 0 ? GetCities(students.StateId) : null;

            HttpResponseMessage Response = client.GetAsync(client.BaseAddress + "/GetStudents/" + id).Result;
            if (Response.IsSuccessStatusCode)
            {
                string data = Response.Content.ReadAsStringAsync().Result;
                model = JsonConvert.DeserializeObject<StudentViewModel>(data);
            }
            
            return View("Create", model);
        }

Create View Code

 @{
                if (Model.CityId != 0)
                {
                   <div class="form-group">
                        <option selected="selected" value="">--Select--</option>
                        @if (Model.CityId > 0 && ViewBag.City != null)
                        {
                            @foreach (var item in ViewBag.City)
                            {
                                <option value=""></option>
                            }
                        }

                        <span asp-validation-for="CityId" class="text-danger"></span>
                    </div>
                }
                else
                {
                    <div class="form-group">
                        <label asp-for="CityId" class="control-label"></label>
                        <select asp-for="CityId" class="form-control">
                            <option value="">--Select City--</option>
                        </select>

                        <span asp-validation-for="CityId" class="text-danger"></span>
                    </div>

                    
                }
            }

tried passing a viewabag from edit get method to the view but I am getting this error error

Sam
  • 1

1 Answers1

0

The error is telling you that ViewBag.City isn't an IEnumerable but is instead a JsonResult. So you can't loop over it like that.

But why is it a JsonResult? Presumably you're mixing up API endpoints here:

ViewBag.City = GetCities(model.StateId)

Is GetCities a controller action? Don't directly combine controller action results like that. (Unless those actions are Web API operations and simply returning your data directly and relying on the framework middleware to turn them into "result" objects, which yours are not.)

Whatever business logic GetCities invokes, this controller action should simply invoke that same business logic. For example, if internally GetCities invokes some service layer method to fetch the "cities" form data, this controller action should just invoke that same thing:

ViewBag.City = someInjectedDependency.GetCities(model.StateId)

(Obviously this is for illustration purposes only, we don't know what your other controller actions are doing or what the rest of your architecture looks like.)


As an aside... names are important. Look at these lines of code:

ViewBag.States = GetState(string.Empty);
ViewBag.City = GetCities(model.StateId);

Will the resulting data have one "state" or a collection of "states"? Will it have one "city" or a collection of "cities"? The code tells us both, and it's telling us both in opposite ways, but both are mutually exclusive.

If something is a collection, make its name plural. If it's a single object, make its name singular. Otherwise you're just asking for confusion and bugs down the road.

David
  • 208,112
  • 36
  • 198
  • 279
  • okay thanks for replying to this , so first thing GetStates() and GetCity() are both api methods , I making a call from mvc controller to api controller to the respective functions . So the goal here is to display state and city dropdown selected by the user in edit operation rightnow only State dropdown is being fetched and not the city. So what should I be doing then ? – Sam Feb 22 '23 at 12:10
  • @semalshastri: And it sounds like those API controller methods are returning a `JsonResult` instead of returning the object(s) directly. You may be able to update your API architecture to return the object(s) directly, but that may be more invasive than what you want. You also may be able to extract the object(s) from the `JsonResult`, but if that involves serialization/de-serialization then it's an unnecessary performance drain. The shortest path here is probably to just not invoke the API methods in this case and just fetch the data you want from the backing logic. – David Feb 22 '23 at 12:13
  • thanks for the quick response , I'll go for extracting object from JSONresult involving involves serialization/de-serialization because that is the only approach I know based on my current knowledge thanks a lot – Sam Feb 22 '23 at 12:18
  • @Sam: It may not involve serialization at all, which is even better. But if your intent is to extract data from a `JsonResult` then [you should be able to do that](https://stackoverflow.com/a/37208962/328193). – David Feb 22 '23 at 12:25
  • thanks David the link you shared was big help , at the I decided to created two different methods with JSON result and list type as return types respectively which pretty much solved the issue I was facing. I know it seems redundant but for now it solved the issue – Sam Feb 23 '23 at 10:12