【问题标题】:MVC 5 ASP.NET Entity Framework Collect Form Data through Range InputMVC 5 ASP.NET Entity Framework 通过范围输入收集表单数据
【发布时间】:2015-06-03 03:05:04
【问题描述】:

所以我正在创建一个调查猴子,一个调查有 4 个类别,每个类别有 5 个问题,HomeController 索引传递来自 Questions 实体的 20 个问题,每个 Questions 必须有一个范围滑块,其值从 1 到 5 ,表单值必须收集到控制器中的一个方法中,然后累积到 QuestionResults 表中并进行处理,然后必须将它们传递到 CategoryResults 并且每个 Category,在 4 个中,必须有一个累积分数,然后它们必须是与 CategoryFeedback(静态)表相比并显示正确的信息。我的 HomeController 的代码和它的索引如下。

我遇到的主要问题是,由于我将表单值作为 FormCollection 的参数传递,我正在努力保持属于某个类别的问题的关系,然后将这些都传递给 CategoryResult处理表。

我们将不胜感激任何帮助

型号:

问题

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace STRA.Models
{
    public class Question
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string CreatedBy { get; set; }
        public DateTime? DateCreated { get; set; }
        public DateTime? DateModified { get; set; }
        public virtual Category Category { get; set; }
        public int CategoryId { get; set; }
        public virtual ICollection<QuestionResult> QuestionResult { get; set; }
        public virtual ICollection<QuestionFeedback> QuestionFeedback { get; set; }
    }
}

问题结果

using IdentitySample.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace STRA.Models
{
    public class QuestionResult
    {
        public int Id { get; set; }
        public DateTime? DateCreated { get; set; }
        public DateTime? DateModified { get; set; }
        public int QuestionScore { get; set; }
        //navigation properties
        public virtual ApplicationUser User { get; set; }
        public ICollection<CategoryResult> CategoryResult { get; set; }
        public virtual Question Question { get; set; }
        public int QuestionId { get; set; }
    }
}

类别结果

using IdentitySample.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace STRA.Models
{
    public class CategoryResult
    {
        public int Id { get; set; }
        public int CategoryScore {get;set;}
        //navigation properties
        public virtual QuestionResult QuestionResult { get; set; }
        public int QuestionResultId { get; set; }

    }
}

我们将不胜感激。 HomeController 索引

@model IEnumerable<STRA.Models.Question>
@{
    //ViewBag.Question.Title = "Survey";
    Layout = "~/Views/Shared/_QuizLayout.cshtml";

}

<div class="hr hr-18 hr-double dotted"></div>

<div class="widget-box">
    <div class="widget-header widget-header-blue widget-header-flat">
        <h4 class="widget-title lighter">STRA</h4>

        @*<div class="widget-toolbar">
                <label>
                    <small class="green">
                        <b>Validation</b>
                    </small>

                    <input id="skip-validation" type="checkbox" class="ace ace-switch ace-switch-4" />
                    <span class="lbl middle"></span>
                </label>
            </div>*@
    </div>
    @*"Create","Home"*@
    @using (Html.BeginForm("Create", "Home", FormMethod.Post))
    {
        @Html.AntiForgeryToken()

        <div class="widget-body">
            <div class="widget-main">
                <!-- #section:plugins/fuelux.wizard -->
                <div id="fuelux-wizard-container">
                    <div class="col-md-12 center">
                        <div class="easy-pie-chart percentage" data-percent="25" data-color="#2679b5">
                            @*<span class="percent">20</span>%*@
                        </div>
                    </div>
                    <div style="display:none;">

                        <!-- #section:plugins/fuelux.wizard.steps -->
                        <ul class="steps">
                            <li data-step="1" class="active">
                                <span class="step">1</span>
                                <span class="Question.Title">Validation states</span>
                            </li>

                            <li data-step="2">
                                <span class="step">2</span>
                                <span class="Question.Title">Alerts</span>
                            </li>

                            <li data-step="3">
                                <span class="step">3</span>
                                <span class="Question.Title">Payment Info</span>
                            </li>

                            <li data-step="4">
                                <span class="step">4</span>
                                <span class="Question.Title">Other Info</span>
                            </li>
                        </ul>

                        <!-- /section:plugins/fuelux.wizard.steps -->
                    </div>

                    <hr />

                    <!-- #section:plugins/fuelux.wizard.container -->
                    <div class="step-content pos-rel">


                        <div class="step-pane" data-step="1">
                            @{

        foreach (var item in Model.Take(5))
        {

            <div class="col-md-12">
                <h4>@Html.DisplayFor(modelItem => item.Title)</h4>

                <div id="slider-eq">
                    <h5 class="pull-left">Strongly Disagree</h5>
                    <h5 class="pull-right">Strongly Agree</h5>
                    <span id="q_@Html.DisplayFor(modelItem => item.Id)" class="ui-slider-purple">3</span>
                    <input type="hidden" id="question_@item.Id" name="question_@item.Id" value="3" />
                </div>
            </div>

        }
        //Model.Skip(5);
                            }
                        </div>
                        <div class="step-pane" data-step="2">
                            @*<div class="center">
                                    <h3 class="blue lighter">This is step 2</h3>
                                </div>*@
                            @{
        foreach (var item in Model.Skip(5).Take(5))
        {


            <div class="col-md-12">
                <h4>@Html.DisplayFor(modelItem => item.Title)</h4>
                <div id="slider-eq">
                    <h5 class="pull-left">Strongly Disagree</h5>
                    <h5 class="pull-right">Strongly Agree</h5>
                    <span id="q_@Html.DisplayFor(modelItem => item.Id)" class="ui-slider-purple">3</span>
                    <input type="hidden" id="question_value" name="question_value" value="3" />
                    <input type="hidden" id="questonId" name="questonId" value="@item.Id" />
                           @*<span class="ui-slider-red">55</span>
                    *@></div>
            </div>

        }
                            }
                        </div>

                        <div class="step-pane" data-step="3">
                            @*<div class="center">
                                    <h3 class="blue lighter">This is step 3</h3>
                                </div>*@
                            @{
        foreach (var item in Model.Skip(10).Take(5))
        {


            <div class="col-md-12">
                <h4>@Html.DisplayFor(modelItem => item.Title)</h4>
                <div id="slider-eq">
                    <h5 class="pull-left">Strongly Disagree</h5>
                    <h5 class="pull-right">Strongly Agree</h5>
                    <span id="q_@Html.DisplayFor(modelItem => item.Id)" class="ui-slider-purple">3</span>
                    <input type="hidden" id="question_@item.Id" name="question_@item.Id" value="3" />
                    @*<span class="ui-slider-red">55</span>
                    *@
                </div>
            </div>

        }
                            }
                        </div>

                        <div class="step-pane" data-step="4">
                            @*<div class="center">
                                    <h3 class="blue lighter">This is step 4</h3>
                                </div>*@
                            @{
        foreach (var item in Model.Skip(15).Take(5))
        {


            <div class="col-md-12">
                <h4>@Html.DisplayFor(modelItem => item.Title)</h4>
                <div id="slider-eq">
                    <h5 class="pull-left">Strongly Disagree</h5>
                    <h5 class="pull-right">Strongly Agree</h5>
                    <span id="q_@Html.DisplayFor(modelItem => item.Id)" class="ui-slider-purple">3</span>
                    <input type="hidden" id="question_@item.Id" name="question_@item.Id" value="3" />
                    @*<span class="ui-slider-red">55</span>
                    *@
                </div>
            </div>

        }
                            }
                        </div>
                    </div>

                    <!-- /section:plugins/fuelux.wizard.container -->
                </div>

                <hr />
                <div class="wizard-actions">
                    <!-- #section:plugins/fuelux.wizard.buttons -->
                    <button type="button" id="previous" class="btn btn-prev">
                        <i class="ace-icon fa fa-arrow-left"></i>
                        Prev
                    </button>

                    <button type="button" id="next" class="btn btn-success btn-next" @*data-last="Finish"*@>
                        Next
                        <i class="ace-icon fa fa-arrow-right icon-on-right"></i>
                    </button>
                    <button id="finish" class="btn btn-success" type="submit">
                        Submit
                        <i class="ace-icon fa fa-arrow-right icon-on-right"></i>
                    </button>
                    <!-- /section:plugins/fuelux.wizard.buttons -->
                </div>

                <!-- /section:plugins/fuelux.wizard -->
            </div><!-- /.widget-main -->
        </div>
    <!-- /.widget-body -->
    }
</div>

HomeController

using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using IdentitySample.Models;
using STRA.Models;
using System.Collections.Generic;
using System.Diagnostics;
using System;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;

namespace IdentitySample.Controllers
{
    [Authorize]
    public class HomeController : Controller
    {
        private ApplicationDbContext db = new ApplicationDbContext();
        //public ActionResult Index()
        public ActionResult Index()
        {
            if (User.IsInRole("Admin"))
            {
                return RedirectToAction("Index", "Dashboard");
            }
            if (User.IsInRole("Sales Consultant"))
            {
                return RedirectToAction("Index", "Reports");
            }


            //loads all questions in
            //var questions = db.Questions.Include(s => s.Survey).Include(c => c.Category);

            var questions = db.Questions.Include(c => c.Category);
            return View(questions.ToList());
            //var questionResults = db.QuestionResults.Include(c => c.Question);
            //return View(questionResults.ToList());

            //viewmodel attempt
            //var viewModel = new SurveyViewModels();
            //viewModel.Questions = db.Questions
            //    .Include(i =>)
        }

        [HttpPost]
        public ActionResult Index(FormCollection result)
        {
            List<QuestionResult> info = new List<QuestionResult>();
            QuestionResult newResult = new QuestionResult();
            var appUser = new ApplicationUserManager(new UserStore<ApplicationUser>(db));
            ApplicationUser user = appUser.FindById(User.Identity.GetUserId());
            foreach (var key in result.AllKeys.Where(k => k.Contains("question")).ToArray<string>())
            {
                string[] keys = key.Split(new char[] { '_' }, StringSplitOptions.RemoveEmptyEntries);

                if (key.Count() > 1)
                {
                    QuestionResult re = new QuestionResult();
                    re.QuestionScore = Convert.ToInt32(result[key]);
                    re.QuestionId = Convert.ToInt32(keys[1]);
                    re.User = user;
                    db.QuestionResults.Add(re);
                }
            }

            db.SaveChanges();

            Debug.WriteLine(result[0]);
            return View();
        }

    }
}

jQuery UI 滑块插件

$("#slider-eq > span").css({ width: '100%', 'float': 'left', margin: '15px' }).each(function () {
            // read initial values from markup and remove that
            var value = parseInt($(this).text(), 10);
            $(this).empty().slider({
                value: value,
                min: 1,
                max: 5,
                range: "min",
                animate: true,
                change: function (event, ui) {
                    //alert(ui.value);
                    $(this).next("[id^=question_]").val(ui.value);
                    //$(this > ).slider("values", $this.data("index"), $this.val());
                }

            });
        });

【问题讨论】:

  • 所以我应该使用像这样的视图模型 public class SurveyViewModels { public List Questions { get;放; } public List CategoryResult { get;放; } public List QuestionResults { get;放; } public List 类别 { 获取;放; } //公共列表 QuestionFeedbacks { get;放; } }
  • 我明白,但范围值没有@Html 助手,所以我坚持使用正常的 html 范围输入,我需要每个问题都与范围输入相关,我不太确定我会怎么做老实说,创建​​这个 ViewModel...感谢您的帮助
  • 嘿伙计,老实说我正在为此苦苦挣扎,您是否可以就如何构建 ViewModel 提供一些帮助?或者,如果您能指出我正确的方向,将不胜感激......谢谢
  • 是的,这正是我需要做的!是的,那么它必须保留它与类别的关系,将它作为 4 个累积分数传递给 CategoryResults,请伙计,如果你能提供解决方案,我可以提供某种形式的付款。我看到你在阿德莱德,我在悉尼。请在我的帐户上给我发电子邮件,我将删除我的详细信息,甚至将我的解决方案发送给您。再次感谢伙计,这件事真的让我发疯了
  • 好的,我也会发布我的脚本,非常感谢,我真的很感激。你是圣人

标签: c# asp.net asp.net-mvc entity-framework


【解决方案1】:

我会在您的 RazorTemplate 中将问题类别添加为 question_id 或 question_name 的前缀,这是通过 FormCollection 获得的

<input type="hidden" id="@(item.category_id)_question_@item.Id" name="@(item.category_id)_question_@item.Id" value="3" />

然后在您的控制器操作中,只需从名称的开头拉出 category_id,这样您就知道您当前正在迭代哪个类别。

【讨论】:

    【解决方案2】:

    您的视图代码正在创建与您的模型无关的表单控件。相反,创建表示您需要在视图中显示/编辑的视图模型,使用强类型帮助器为您提供 2 路模型绑定并回发您的视图模型。

    查看模型

    public class SurveyVM
    {
      public List<CategoryVM> Categories { get; set; }
      // add any other properties of Survey you need to display/edit (e.g. ID, Title etc)
    }
    
    public class CategoryVM
    {
      public List<QuestionVM> Questions { get; set; }
      // add any other properties of Category you need to display/edit (e.g. ID, Title etc)
    }
    
    public class QuestionVM
    {
      public int Id { get; set; }
      public string Title { get; set; }
      public int Score { get; set; }
      // Do not include properties such as DateCreated, User etc
    }
    

    控制器

    public ActionResult Index()
    {
      SurveyVM model = new SurveyVM();
      // populate the categories and for each category, populate the associated questions
      return View(model);
    }
    
    [HttpPost]
    public ActionResult Index(SurveyVM model)
    {
      // loop through each Category, and foreach category loop through each Question to build your `List<QuestionResult>`
    }
    

    查看

    @model yourAssembly.SurveyVM
    @using (Html.BeginForm())
    {
      // add elements for properties of SurveyVM (ID, Title etc)
      for(int i = 0; i < Model.Categories.Count; i++)
      {
        <div class="category">
          // add elements for properties of each CategoryVM (ID, Title etc)
          @for (int j = 0; j < Model.Categories[i].Questions.Count; j++)
          {
            <div class="question">
              @Html.HiddenFor(m => m.Categories[i].Questions[j].Id)
              @Html.DisplayFor(m => m.Categories[i].Questions[j].Title)
              @Html.TextBoxFor(m => m.Categories[i].Questions[j].Score)
            </div>
          }
        </div>
      }
      <input type="submit" .../>
    }
    

    【讨论】:

    • 添加了答案的第一部分。暂时忘记脚本。需要确保您首先了解模型绑定的工作原理,并且无论如何您的脚本都存在问题 - 您有重复的 id 属性("slider-eq"),这是无效的 html 和 $("#slider-eq &gt; span") 只会选择第一个.稍后我将更新您如何更正此问题并简化代码的其他方面。还建议您首先在SurveyVM 中硬编码一些CategoryVMQuestionVM 对象以进行测试。
    • 非常感谢,我真的很感激。我现在就测试一下
    • 嘿,伙计,我正在使用你的方法,但我在索引视图中收到一个空异常错误,我也尝试通过以下发布操作循环 [HttpPost] public ActionResult IndexSurveyViewModel(SurveyViewModel model) { // 遍历每个类别,foreach 类别循环遍历每个问题以构建您的List&lt;QuestionResult&gt; foreach (var category in model.Categories) { foreach (var question in category.Questions) { } } }
    • 您从哪里获得NullReferenceException?我注意到在您的 POST 方法中您只使用了return View();,这可能会产生异常(除非您为所有属性添加了隐藏输入)。您发布时模型是否正确填充?
    • 我现在禁用 post 方法,因为我还没有返回任何东西。我在 Http get 上收到 NullExceptionError,所以我的视图中没有真正填充任何内容
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 2018-04-24
    • 2015-06-10
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多