【问题标题】:Persisting data back to ViewModel with a dynamic .aspx page ASP.NET MVC 3使用动态 .aspx 页面 ASP.NET MVC 3 将数据持久化回 ViewModel
【发布时间】:2013-03-25 00:56:11
【问题描述】:

我有一个使用数据库中的对象动态创建的视图。如果它是动态创建的,如何从我的视图中获取值并将它们传递给我的视图模型?我知道这个问题很模糊,但希望通过我的代码可以帮助你。

查看

  <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% using (Html.BeginForm()) {%>
<h1>Survey Says...</h1>
<ol>       
<li>
    Name: <input type="text" disabled="true" name="name" value="<%= Model.Name %>"/> 
</li>                                                  

<li>
    Email: <input type="text" disabled="true" name="email" value="<%= Model.Email %>"/>
</li>

<%foreach(SurveyQuestions s in Model.myQuestions)
  { %>   

    <li>    <%= s.QuestionText %>    <br />
    <%
    foreach(SurveyQuestionAnswers q in s.QuestionAnswers)
    {

    %>
        <input type="radio" name="rbGroup<%= q.Id%>"/> <%= q.DisplayText %><br/>

        <% 
     if(q.IsEditable)
     {
         %>
            <input type="text" id="txtOther<%= q.Id %>"/>
         <%
     }
    }
      %>           


    </li>

 <% } 

  %>      
           <li>
    <input type="submit" value="Save" id="save-button" />
</li>

</ol>
<% } %>

SurveyQuestion 类

public class SurveyQuestions
{
    public string QuestionText { get; set; }
    public List<SurveyQuestionAnswers> QuestionAnswers { get; set; }
    public int Id { get; set; }
}

SurveyQuestionAnswers 类

 public class SurveyQuestionAnswers
{
    public int Id { get; set; }
    public string DisplayText { get; set; }
    public bool IsEditable { get; set; }
}

我草率的 ViewModel

          public class GfcPreInterventionSurveyViewModel
{
    static SurveyService myService = new SurveyService(new SurveyRepository());

    [DisplayName("Name")]
    [Required(ErrorMessage = "Name is required.")]
    public string Name { get; set; }

    [DisplayName("Work Email")]
    [Email(ErrorMessage = "The email you entered is not valid.")]
    public string Email { get; set; }

    [DisplayName("Gender")]
    [Required(ErrorMessage = "Gender is required.")]
    public string Gender { get; set; }


    [DisplayName("Country")]
    [Required(ErrorMessage = "Country is required.")]
    public string Country { get; set; }

    [DisplayName("Business")]
    [Required(ErrorMessage = "Please select a business unit.")]
    public string BusinessUnit { get; set; }

    public SelectList GenderList;
    public SelectList BusinessList;
    public SelectList CountryList;
    public SelectList RoutineList;
    public SelectList ReasonList;
    public SelectList ActivityList;
    public SelectList HealthList;
    public SelectList EnergyList;

    public SelectListItem GenderItem;
    public SelectListItem BusinessItem;
    public SelectListItem CountryItem;
    public SelectListItem RoutineItem;
    public SelectListItem ReasonItem;
    public SelectListItem ActivityItem;
    public SelectListItem HealthItem;
    public SelectListItem EnergyItem;


    public Boolean ToGetFit { get; set; }
    public Boolean ToChallengeMyself { get; set; }
    public Boolean ToIncrEnergy { get; set; } 
    public Boolean ToBuildMorale { get; set; }
    public Boolean ToBeHealthier { get; set; }
    public Boolean ChallengeOther { get; set; }

    public string OtherString { get; set; }    

    [DisplayName("Exercise Routine")]
    [Required(ErrorMessage = "Which option describes your exercise routine.")]
    public string Routine { get; set; }


    [DisplayName("Physical Activity")]
    [Required(ErrorMessage = "Which option describes your physical activity.")]
    public string Activity { get; set; }


    [DisplayName("Overall Health")]
    [Required(ErrorMessage = "Which option describes your overall health.")]
    public string Health { get; set; }

    [DisplayName("Energy")]
    [Required(ErrorMessage = "Which option best describes your energy.")]
    public string Energy{ get; set; }

    public int ReasonsForChallenge { get; set; }



    public List<SurveyQuestions> myQuestions = new List<SurveyQuestions>();
    //public List<SurveyQuestionAnswers> myAnswers;


    public void build(int id)
    {
        var myService = new SurveyService(new SurveyRepository());

        myQuestions = myService.GetSurveyQuestions(id);

            }

我的 getSurveyQuestions 方法返回一个 SurveyQuestions 对象列表。

目前,在我的控制器中,当点击保存时,会调用 post 方法。这是我想用视图模型中的值更新我的数据库的地方,但是因为我的页面是如此动态,我无法访问用户的输入。

我的控制器:

public class SurveyController : WidgetControllerBase
{
    #region Private Members
    private readonly ISurveyRepository _surveyRepository;
    #endregion

    #region Constructors

    public SurveyController(ISurveyRepository surveyRepository)
    {
        if (surveyRepository == null)
        {
            throw new ArgumentNullException("surveyRepository");
        }
        _surveyRepository = surveyRepository;
    }

    #endregion

    // GET: /Survey/GfcPreIntervention
    public ActionResult GfcPreInterventionSurvey()
    {

        var surveyService = new SurveyService();
        var vm = new GfcPreInterventionSurveyViewModel();

        vm.build(AppUserInstance.Id);

        //paymentService.SetDVDShipped(payment.PaymentId);
        return View(vm);
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult GfcPreInterventionSurvey(GfcPreInterventionSurveyViewModel viewModel)       
    {
        return View(viewModel);                     
    }
}

【问题讨论】:

  • 您不会将值从视图传递到视图模型。您通过model binding 将它们传回控制器。您没有遇到问题,因为您的页面是如此动态,而是因为您没有遵循模型绑定器工作的正确约定。
  • 那你能帮我解决一下约定吗?是否有可能让这个页面如此动态并且仍然能够将这些值传回我的数据库?
  • 我应该使用 Html Helper 方法吗??
  • 是的,您必须使用 Html 辅助方法。

标签: asp.net-mvc asp.net-mvc-3 mvvm


【解决方案1】:

由于您的页面是高度动态的,也许您最好编写一个自定义模型绑定器。虽然这个词听起来很吓人,但实际上并没有那么复杂。

您只需创建一个实现IModelBinder 的类。在此类中,您可以访问表单集合并可以使用它填充任何复杂的对象

以下是一些值得一看的例子

http://dotnetslackers.com/articles/aspnet/Understanding-ASP-NET-MVC-Model-Binding.aspx

http://ivanz.com/2010/11/03/custom-model-binding-using-imodelbinder-in-asp-net-mvc-two-gotchas/

如您所见,使用辅助方法(最好使用 Razor)将清理 UI 代码

【讨论】:

  • 嘿钦塔纳!看起来它可能会起作用。我唯一的问题是,关于我的控制器中的 Post 方法。看起来像这样--->要编辑原始帖子。如何修改我的 Post 方法以返回我创建的 Model Binder 类?
  • 在 DotNetSlackers 页面上,示例 4。他只是传回了两个列表。他做了什么来完成这项工作?那对我来说是完美的。我可以给我所有的单选按钮起相同的名字,并把一个计数器连接到末尾或其他东西
  • 是的,对要映射到列表中的项目使用相同的名称(而不是 ID)。这样,当您在自定义模型活页夹中时,您就会知道要在表单集合中查找什么。干杯
  • 我需要以某种方式连接自定义模型绑定器吗?
  • 是的,你必须告诉 MVC 运行时模型绑定器关联的类型。 Application_Start 将是一个很好的地方,使用类似 ModelBinders.Binders.Add(typeof (YourModel), new ModelBunderForYourModel());.. 让我知道进展如何.. 干杯
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-08
  • 1970-01-01
  • 2012-04-11
  • 2012-06-08
相关资源
最近更新 更多