开发者

Strange problem with ASP.NET MVC DropDownFor

Hi,

I have the following in my view :

<form id="list_ad" method="get" class="adListFilter" action="<%=Url.Action("List", "Ad") %>">
    <%: Html.DropDownListFor(model => model.LS.L1, Model.LS.Location1List, "-- Place --", new { @class = "dd1" })%>
    ...
</form>

model.LS.L1 is int? Model.LS.Location1List is SelectList (no selection set only the list)

First visit on the view will look grate, the LocationDropDown will contain correct values and the model.LS.L1 will be set to null.

Then I submit the form and in the control action I will set the model.LS.L1 to 3. I have also checked that this is true at the end of the action ("return View(data);").

The problem is that the option with value 3 is not set as selected in the dropdown control? The model.LS.L1 seems to be null even when it was set to 3 in the action?

What can be the problem?

BestRegards

Edit1:

Action :

    public ActionResult List(AdList data)
    {
        AdModel adModel = new AdModel();
        AccountModel accountModel = new AccountModel();
        FilterModel filterModel = new FilterModel();
        List<Ad> adList;

        AdCategoryPreset adCategoryPreset = null;

        int adCount;


        if (data == null)
            data = new AdList();

        adCategoryPreset = this.setDefaultPresets(data);

        this.setDefaultViewData(data, adCategoryPreset);
        this.SetDefaultSettingsOnListAdListSettings1(data.ALS);

        data.ALC.MVA = new List<AdListItem>();

        FillLocationOfList(data.ALC.MVA);
        FillCategoriesOfList(data.ALC.MVA);

        FilterHandler.Instance.SetFilter(data.F, data.CS.LastSelectedCategory.Value, FilterType.Display, adCategoryPreset.ToFilterValues());

        adList = adModel.SearchAds(data, DateTime.Now.AddMonths(-int.Parse(ConfigurationManager.AppSettings["ShowAdsThatIsEqualOrLessThenMonth"])), out adCount);

        data.ALC.MVA.AddRange(Mapper.Map<IList<Ad>, IList<AdListItem>>(adList));
        data.ALS.TC = adCount;
//When submitting a parameter on the incoming data will be set and if this is set then the 
//data.LS.L1 will be set to 3. I have cheked that data.LS.L1 is set to 3 when returning a submit.
        return View(data);
    }

Model :

public class AdList
    {
        public AdList()
        {
            this.LS = new LocationSelect();
this.P = new AdListPresets();
        }

public LocationSelect LS { get; set; }
}

    public class LocationSelect
    {
        public int? L1 { get; set; }
        public int? L2 { get; set; }
        /// <summary>
        /// Used when multiple choise is possible
        /// </summary>
        public List<int> L3 { get; set; }

        public SelectList Location1List { get; set; }
        public SelectList Location2List { get; set; }

        public LocationSelect()
        {
            L3 = new List<int>();
            Location1List = new SelectList(new List<SelectListItem>(), "Value", "Text", -1);
            Location2List = new SelectList(new List<SelectListItem>(), "Value", "Text", 0);
        }
    }

Edit2:

If I place a

 <%: Html.HiddenFor(c => c.LS.L1) %>

in the view, it will be renderd like this :

<input id="LS_L1" type="hidden" value="" name="LS.L1">

The value should be 3 here

Edit3:

private void setDefaultViewData(AdList adList, AdCategoryPreset adCategoryPreset)
{
    this.SetDefaultSettingsOnCategories(adList.CS, adCategoryPreset);
    SetDefaultSettingsOnLocations(adList.LS, adCategoryPreset);
}

public static void SetDefaultSettingsOnLocations(LocationSelect locationSelect, AdCategoryPreset adCategoryPreset)
{
    LocationModel locationModel = new LocationModel();
    List<ModelViewLocation> mvLocationList = new List<ModelViewLocation>();

    List<Location> selectedLocationList = new List<Location>();

    if (locationSelect != null)
    {
        mvLocationList = Mapper.Map<IList<Location>, IList<ModelViewLocation>>(locationM开发者_运维百科odel.GetLocationsByParentId(null)).ToList();

        if (adCategoryPreset != null && adCategoryPreset.LocationIdList.Length > 0)
        {
            selectedLocationList = new List<Location>();
            foreach (string locationId in adCategoryPreset.LocationIdList.Split(','))
                selectedLocationList.Add(locationModel.GetLocation(int.Parse(locationId)));

            locationSelect.Location1List = new SelectList(mvLocationList, "Id", "Name", selectedLocationList[0].ParentId);
            locationSelect.L1 = selectedLocationList[0].ParentId;

            mvLocationList = Mapper.Map<IList<Location>, IList<ModelViewLocation>>(locationModel.GetLocationsByParentId(selectedLocationList[0].ParentId)).ToList();
            locationSelect.Location2List = new SelectList(mvLocationList, "Id", "Name");

            locationSelect.L3 = selectedLocationList.Select(c => c.Id).ToList();
        }
        else if (locationSelect.L1.HasValue && locationSelect.L1.Value > 0)
        {
            locationSelect.Location1List = new SelectList(mvLocationList, "Id", "Name"); //, locationModel.GetLocation(locationSelect.L1.Value));

            mvLocationList = Mapper.Map<IList<Location>, IList<ModelViewLocation>>(locationModel.GetLocationsByParentId(locationSelect.L1)).ToList();
            locationSelect.Location2List = new SelectList(mvLocationList, "Id", "Name");
        }
        else
        {
            mvLocationList = Mapper.Map<IList<Location>, IList<ModelViewLocation>>(locationModel.GetLocationsByParentId(null)).ToList();

            locationSelect.Location1List = new SelectList(mvLocationList, "Id", "Name", 0);
            locationSelect.Location2List = new SelectList(new List<object>(), null);
        }
    }

}

When loading the page the first time the else part will be runned in the SetDefaultSettingsOnLocations method. The second time the first if section will be runned. The middle part(else if) will never be triggered in this scenario. I have checked that this is true in debug mode.


Your problem here is ModelState. You POST to your Action and return the same view. The second time the view is rendered it will look at the ModelState and use those values to fill your controls. This is used for when validation fails:

if(!ModelState.IsValid)
    return View(model);

Is this scenario the values that the user entered are again selected. Your case is simple to fix, just use:

ModelState.Clear();

before you return the View.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜