[英]Passing local variable in Razor view by JavaScript to java script function and then to C# method
我想将@survey
作为class Survey
对象传递给JavaScript函数SubmitClick
,然后传递给SubmitSurvey
中的PersonController.cs
我的按钮:单击javascript:SubmitClick
参数传递给javascript:SubmitClick
<button class='mybutton' type='button' onclick="javascript:SubmitClick(@Model.Item1.Id, @survey);">Save Survey</button>
和JavaScript函数:
function SubmitClick(pid, sid) {
var url = '@Url.Action("SubmitSurvey", "Person")';
$.post(url, { personId: pid, survey: sid }, function (data) {
alert('updated' + pid);
});
}
和我想传递给@survey
:
public void SubmitSurvey(int personId, Survey survey) {
}
结果是:
我想指出,传递@survey.Id
(int)起作用,所以唯一的问题是传递@survey
。
将参数传递给Java脚本函数时弹出错误。
编辑
该按钮位于foreach循环内,模型有点复杂。 我可以在循环中序列化它吗?
我将调查清单从此处传递给视图:
public ActionResult _Survey1(int id) {
System.Diagnostics.Debug.WriteLine("PASSED ID: " + id);
Person person = db.Persons.Find(id);
//Passing a Tuple to Partial View, I want to pass copies further I use copying constructor
List<Survey> localSurveysCopy = new List<Survey>();
foreach (Survey survey in db.Surveys) {
localSurveysCopy.Add(new Survey(survey));
}
var tuple = new Tuple<Person, List<Survey>>(person, localSurveysCopy) { };
return PartialView(tuple);
}
风景:
@using WebApplication2.Models
@model System.Tuple<Person, List<Survey>>
<hr />
<h1>Surveys</h1>
<input type="button" id="Coll" value="Collapse" onclick="javascript:CollapseDiv()" />
@{int i = 1;}
@foreach (var survey in Model.Item2) {
using (Html.BeginForm()) {
<h2>Survey @(i)</h2>
<p />
@Html.EditorFor(x => survey.Questions)
<button class='mybutton' type='button' onclick="javascript:SubmitClick(@Model.Item1.Id, @Newtonsoft.Json.JsonConvert.SerializeObject(survey));">Save Survey</button>
}
i++;
<hr style="background-color:rgb(126, 126, 126);height: 5px" />
}
<hr />
剧本。 我认为我必须直接通过变量,因为我有很多调查和很多按钮:
function SubmitClick(pid, sid) {
var url = '@Url.Action("SubmitSurvey", "Person")';
var objSurvey = $.parseJSON(sid);
$.post(url, { personId: pid, survey: objSurvey }, function (data) {
alert('updated person' + pid + ' survey ' + sid);
});
}
我得到:
A first chance exception of type 'System.Web.HttpException' occurred in System.Web.dll
A first chance exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll
A first chance exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll
A first chance exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll
A first chance exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll
A first chance exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll
A first chance exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll
A first chance exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll
A first chance exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in System.Web.Mvc.dll
A first chance exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in System.Web.Mvc.dll
该类Survey看起来像:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace WebApplication2.Models {
public class Survey {
public int Id { set; get; }
public virtual ICollection<Question> Questions { set; get; }
public Survey() { }
public Survey(Survey survey) {
Id = survey.Id;
Questions = new List<Question>();
System.Diagnostics.Debug.WriteLine("SURVEY " + survey.Questions == null);
foreach (Question question in survey.Questions) {
Questions.Add(new Question(question));
}
}
}
public class Question {
public int Id { set; get; }
public string QuestionText { set; get; }
public virtual ICollection<Answer> Answers { set; get; }
public virtual Survey Survey { get; set; }
public string SelectedAnswer { set; get; } //this field is SET after clicking SAVE button
public Question() { }
public Question(Question question) {
Id = question.Id;
QuestionText = question.QuestionText;
Answers = question.Answers;
Survey = question.Survey;
SelectedAnswer = "";
}
}
public class Answer {
public int Id { set; get; }
public string AnswerText { set; get; }
public virtual Question Question { get; set; }
public virtual ICollection<Person> Persons { get; set; }
}
}
您不能仅将C#对象传递给JS并将其发回。
你应该:
控制器:
string json = JsonConvert.SerializeObject(survey);
标记:
<button class='mybutton' type='button' onclick="javascript:SubmitClick(@Model.Item1.Id, @json);">Save Survey</button>
标记:
function SubmitClick(pid, sid) {
var objSurvey = $.parseJSON(sid);
var url = '@Url.Action("SubmitSurvey", "Person")';
$.post(url, { personId: pid, survey: objSurvey }, function (data) {
alert('updated' + pid);
});
}
控制器:
public void SubmitSurvey(int personId, Survey survey) { }
更新:
由于类之间存在循环引用,因此您的Survey实体无法正确序列化。 因此,您这里没有什么选择:
你做错了。
基本上,当您执行@survey
,您正在查看服务器端代码。 在客户端,此@survey
是强类型clr类的一个实例,将转换为字符串,并且您知道在将对象转换为字符串时会发生什么,将其Type转换为字符串,即
@survey.ToString() == "WebApplications2.Models.Survey"
显然这是错误的原因,最后,您的按钮标签的标记实际上变为:
<button class='mybutton' type='button'
onclick="javascript:SubmitClick(@Model.Item1.Id,
WebApplications2.Models.Survey);">
Save Survey
</button>
您基本上应该首先在服务器端序列化@survey
对象,并将其存储在隐藏变量中,即
@Html.Hidden("hdnSurvey", Newtonsoft.Json.JsonConvert.SerializeObject(Model))
并在JavaScript中使用此隐藏变量
即
function SubmitClick(pid) {
var objSurvey = $.parseJSON( $('#hdnSurvey').val());
var url = '@Url.Action("SubmitSurvey", "Person")';
$.post(url, { personId: pid, survey: objSurvey }, function (data) {
alert('updated' + pid);
});
}
发回@survey
变量是没有意义的,UI的更改不会从变量中反映出来,但是从HTML输入中,您真正需要的是序列化表单。
这是您真正需要的完整解决方案。
模型
public class Person
{
public int Id { set; get; }
}
public class Survey
{
public int Id { set; get; }
public virtual ICollection<Question> Questions { set; get; }
}
public class Question
{
public int Id { set; get; }
public string QuestionText { set; get; }
public virtual ICollection<Answer> Answers { set; get; }
public int SelectedAnswerId { set; get; } // Notice that I change it into int not string
}
public class Answer
{
public int Id { set; get; }
public string AnswerText { set; get; }
}
控制者
public ActionResult Index()
{
var person = new Person { Id = 1 };
var survey = new Survey
{
Id = 12,
Questions = new List<Question>
{
new Question
{
Id = 34,
QuestionText = "What is your favorite language?",
Answers = new List<Answer>
{
new Answer { Id = 56, AnswerText = "A#" },
new Answer { Id = 57, AnswerText = "B#" },
new Answer { Id = 58, AnswerText = "C#" }
}
}
}
};
var model = new Tuple<Person, List<Survey>>(person, new List<Survey> { survey });
return View(model);
}
[HttpPost]
public ActionResult SubmitSurvey(int personId, Survey survey)
{
return Json(new { success = true });
}
Index.cshtml
@model Tuple<Person, List<Survey>>
@{
ViewBag.Title = "Index";
}
<h2>Surveys</h2>
@{int i = 1;}
@foreach (var survey in Model.Item2)
{
using (Html.BeginForm())
{
<h3>Survey @(i++)</h3>
@Html.HiddenFor(x => survey.Id)
@Html.EditorFor(x => survey.Questions)
<button class="mybutton" type="button">Save Survey</button>
}
}
@section Scripts
{
<script>
$(".mybutton").click(function () {
var personId = "@Model.Item1.Id";
var survey = $(this).closest("form").serialize();
var data = survey + "&personId=" + personId;
$.ajax({
type: "POST",
url: "@Url.Action("SubmitSurvey", "Survey")",
data: data,
traditional: true,
success: function (data) {
alert("submitted :" + data.success);
}
});
});
</script>
}
EditorTemplates / Question.cshtml
@model Question
<h3>@Model.QuestionText </h3>
@Html.HiddenFor(x => x.Id)
@foreach (var a in Model.Answers)
{
<label>@Html.RadioButtonFor(b => b.SelectedAnswerId, a.Id) @a.AnswerText</label>
}
结果
如果用户在第一个问题的第一个调查中选择了B#
,则提交的调查将返回SelectedAnswerId
为57。其他属性(如Answers
和QuestionText
为null,对于保存并不重要,因此请保留。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.