将selectlistitems绑定到viewmodel的正确方法

时间:2015-12-27 14:28:53

标签: c# asp.net-mvc

我已经多次问过这类问题,但我无法找到一种正确而干净的方法来做到这一点。 在帖子操作上,我的PossibleAnswers属性不再设置(正常,因为我没有将其发回)。我应该如何设置它,因为数据来自数据库?再次查询数据库对我来说似乎不合逻辑,虽然我认为它有效。有没有其他解决方案,比如缓存列表?

控制器

public ActionResult EditFirstCharac()
{
        var userId = _userService.GetUserIdFromName(_userName);
        var charac = _characService.GetAllUserCharacteristics(userId).ToList().FirstOrDefault(p => p.SelectedAnswer != null);

        var vm = new EditCharacViewModel()
        {
            CharacId = charac.Id,
            IsKey = charac.IsKey,
            Question = charac.Question.Title,
            Weight = charac.Weight,
            PossibleAnswers = charac.Question.PossibleAnswers.ToListSelectListItem(p => p.Id.ToString(), p => p.Label).ToList()
        };

        return View("Edit", vm);
    }

    [HttpPost]
    public ActionResult EditFirstCharac(EditCharacViewModel vm)
    {
        if (ModelState.IsValid)
        {
            // OK, save to DB or whatever
        }
        // KO, PossibleAnswers is empty
        return View("Edit", vm);
    }

视图模型

public class EditCharacViewModel
{
    public int CharacId { get; set; }
    public string Question { get; set; }

    [Range(0, 5)]
    public int Weight { get; set; }

    public bool IsKey { get; set; }
    public List<SelectListItem> PossibleAnswers { get; set; }
    public string SelectedAnswer { get; set; }
}

查看     @model Dating.WebSite.ViewModels.Profile.EditCharacViewModel

@using (Html.BeginForm("EditFirstCharac", "Profile"))
{
    <div>@Model.Question</div>

    @Html.EditorFor(p => p.IsKey)

    @Html.EditorFor(p => p.Weight)

    @Html.DropDownListFor(p => p.SelectedAnswer, Model.PossibleAnswers)

    @Html.HiddenFor(p => p.Question, new { id = "Question" })
    @Html.HiddenFor(p => p.CharacId, new { id = "CharacId" })
    <input type="submit" />
}

1 个答案:

答案 0 :(得分:1)

  

在发布操作上,我的PossibleAnswers属性不再设置   (正常情况下,因为我没有发回来)。

这是正确和预期的行为。 Http是无状态的。因此,您的第二个请求(POST)不知道您之前的请求(GET请求)中#include <stdio.h> #include <string.h> int main(void) { char s1[100], s2[100]; size_t i, len1, len2; puts("First string?"); if (!fgets(s1, sizeof s1, stdin)) return 1; len1 = strlen(s1); if (len1 > 0 && s1[len1 - 1] == '\n') s1[--len1] = '\0'; puts("Second string?"); if (!fgets(s2, sizeof s2, stdin)) return 1; len2 = strlen(s2); if (len2 > 0 && s2[len2 - 1] == '\n') s1[--len2] = '\0'; if (len1 + len2 >= sizeof s1) return 2; /* copy the characters from s2 including the final '\0' */ for (i = 0; i <= len2; i++) { s1[len1 + i] = s2[i]; } puts(s1); return 0; } 属性的含义

  

我应该如何重新设置,因为数据来自数据库?查询   db再次对我来说似乎不合逻辑

是。您需要重新加载数据。正如我之前提到的,Http是无状态的,您当前的(POST)请求将不会包含您在先前请求中加载的数据。在ASP.NET Web表单中,我们使用ViewState在请求之间保留数据。这更像是一个黑客。下拉列表的内容被加密为字符串并存储在隐藏字段中并发回服务器。回发后,服务器将解密字符串并再次加载下拉列表。这个黑客/技巧通常违反了Http的概念,其中一个请求不应该对先前的请求有所了解。

所以你应该做的是

PossibleAnswers