【发布时间】:2014-01-28 11:01:52
【问题描述】:
在我的项目中,我有一个动态填充的视图,在一个屏幕/页面上创建一个或多个表单。我设法动态地给每个表单一个唯一的 id,但是当一个页面上有多个表单时,当只提交一个时返回所有表单的数组,我不知道如何识别正在提交的实际实例数组。
这是我的观点;
@using Microsoft.AspNet.Identity
@model IEnumerable<Template.Models.GetQuestionViewModel>
@{
ViewBag.Title = "View question";
ViewBag.Page = Model.First().PageNumber;
}
@Html.AntiForgeryToken();
@foreach (var q in Model.OrderBy(o => o.QuestionRanking))
{
Html.BeginForm("ViewQuestion", "Question", FormMethod.Post, new { @class = "form-horizontal", id = @q.formNumber, role = "form" });
var qtype = q.QuestionTypeId;
<div>
<h1>@q.QuestionRanking. @q.Question1</h1>
</div><div class="form-group">
@switch (qtype)
{
case 1:
// Textbox
@Html.TextArea("Answer", q.Answer, new { @class = "form-control", rows="4", cols="10" })
break;
case 2:
// Dropdown
<select class="form-control" id="Answer" name="Answer">
@foreach (var item in q.QuestionOptions.OrderBy(o => o.QuestionOptionRanking))
{
if (q.Answer == item.QuestionOption1)
{
<option value="@item.QuestionOption1" selected>@item.QuestionOption1</option>
}
else
{
<option value="@item.QuestionOption1">@item.QuestionOption1</option>
}
}
</select>
break;
...
}
</div>
<input type="hidden" name="QuestionId" value="@q.Id" /
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" name="@q.formNumber" class="btn btn-primary" value="Save answer" />
</div>
</div>
<br />
<hr />
**Html.EndForm();**
}
这是我的控制器;
using System.Web.Mvc;
using Template.Models;
using Microsoft.AspNet.Identity;
using System.Linq;
using System.Collections.Generic;
using System;
namespace Template.Controllers
{
public class QuestionController : Controller
{
private WebTemplateEntities db = new WebTemplateEntities();
// GET: /Questions/ViewQuestion/5
[HttpGet]
public ActionResult ViewQuestion(int page = 1)
{
// If user is not logged in, push them back to Login
var userId = User.Identity.GetUserId();
if (userId == null)
{
return RedirectToAction("Login", "Account");
}
// Get the list of Questions and Response options from the database
List<GetQuestionViewModel> quest = new List<GetQuestionViewModel>();
var i = 1; // for form array
foreach (var item in db.Questions.Where(q => q.PageNumber == page))
{
//Check if user has submitted a response
var reply = db.Responses.Where(r => r.QuestionId == item.Id && r.UserId == userId).Select(r => r.Answer).ToList();
//If no input, do not look for answers
if (reply.Count == 0)
{
quest.Add(new GetQuestionViewModel()
{
Id = item.Id,
QuestionOptions = db.QuestionOptions
.Where(k => k.QuestionId == item.Id)
.ToList(),
PageNumber = item.PageNumber,
Question1 = item.Question1,
QuestionRanking = item.QuestionRanking,
QuestionTypeId = item.QuestionTypeId,
formNumber = "form" + i // for form array
});
}
else //If user has input answers find them
{
quest.Add(new GetQuestionViewModel()
{
Id = item.Id,
QuestionOptions = db.QuestionOptions
.Where(k => k.QuestionId == item.Id)
.ToList(),
PageNumber = item.PageNumber,
Question1 = item.Question1,
QuestionRanking = item.QuestionRanking,
QuestionTypeId = item.QuestionTypeId,
formNumber = "form" + i, // for form array
Answer = reply.First()
});
}
i++; // for form array
}
return View(quest);
}
// POST: /Questions/ViewQuestion/5
[HttpPost]
public ActionResult ViewQuestion([Bind(Include = "QuestionId, Answer, UserId")] ResponseViewModel responseViewModel)
{
// Get page and question id
var page = System.Web.HttpContext.Current.Request["page"]; //NOTE: Problem with binding on multi form pages
var qId = System.Web.HttpContext.Current.Request["QuestionId"]; //NOTE: Problem with binding on multi form pages
var newAnswer = System.Web.HttpContext.Current.Request["Answer"];
int a = Convert.ToInt32(qId); //NOTE: Problem with binding on multi form pages
//Check if user has previously answerer
List<Response> reply = new List<Response>();
reply = (from r in db.Responses
where r.QuestionId == a && r.UserId == responseViewModel.UserId
select r ).ToList();
// If this is the first time the user has answered, add the response
if (reply.Count() == 0)
{
Response re = new Models.Response();
re.Answer = responseViewModel.Answer;
re.UserId = responseViewModel.UserId;
re.QuestionId = responseViewModel.QuestionId;
re.Source = "Web";
re.Status = "New";
re.DateStamp = System.DateTime.Now;
db.Responses.Add(re);
db.SaveChanges();
}
else // If the user has already answered move the original responses to AuditTrail
{
var ans = reply.Select(r => r.Id).First();
var dos = reply.Select(r => r.Answer).First();
AuditTrail au = new Models.AuditTrail();
au.ResponseId = ans;
au.OriginalData = dos;
au.DateChanged = System.DateTime.Now;
db.AuditTrails.Add(au);
db.SaveChanges();
// Update user's response
var stat = "Update, 1"; // NOTE: Work in progress; create array of updates to track number of updates
var updateAnswer = db.Responses.Single(q => q.Id == ans);
updateAnswer.Answer = newAnswer;
updateAnswer.Status = stat;
db.SaveChanges();
}
return RedirectToAction("ViewQuestion/" + page);
}
}
}
还有更多问题类型的案例,但为了清楚起见,我将它们省略了。
如果每个屏幕有多个问题和响应,则发布操作会返回页面上所有表单的数组。从我最初的调查来看,我无法确定如何确定提交了哪个特定表单,因此我不知道如何获得正确的回复。
有办法吗?
【问题讨论】:
标签: c# asp.net-mvc model-view-controller view