通过JavaScript将Razor视图中的局部变量传递给java脚本函数,然后传递给C#方法

通过JavaScript将Razor视图中的局部变量传递给java脚本函数,然后传递给C#方法,javascript,.net,asp.net-mvc,razor,Javascript,.net,Asp.net Mvc,Razor,我想将@survey传递给JavaScript函数SubmitClick,然后传递给PersonController.cs中的SubmitSurvey 我的按钮:单击时将参数传递给javascript:SubmitClick <button class='mybutton' type='button' onclick="javascript:SubmitClick(@Model.Item1.Id, @survey);">Save Survey</button> 以及我要

我想将
@survey
传递给JavaScript函数
SubmitClick
,然后传递给
PersonController.cs中的
SubmitSurvey

我的按钮:单击时将参数传递给
javascript:SubmitClick

<button class='mybutton' type='button' onclick="javascript:SubmitClick(@Model.Item1.Id, @survey);">Save Survey</button>
以及我要传递到的方法
@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);
 }
我得到:

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
班级调查如下所示:

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; }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Web;
命名空间WebApplication2.Models{
公营班级调查{
公共int Id{set;get;}
公共虚拟ICollection问题{set;get;}
公共调查(){}
公众调查(调查){
Id=survey.Id;
问题=新列表();
System.Diagnostics.Debug.WriteLine(“调查”+调查.问题==null);
foreach(调查中的问题。问题){
添加(新问题(问题));
}
}
}
公开课问题{
公共int Id{set;get;}
公共字符串QuestionText{set;get;}
公共虚拟ICollection答案{set;get;}
公共虚拟调查{get;set;}
公共字符串SelectedAnswer{set;get;}//此字段在单击“保存”按钮后设置
公共问题(){}
公众问题{
Id=question.Id;
QuestionText=question.QuestionText;
答案=问题。答案;
调查=问题。调查;
SelectedAnswer=“”;
}
}
公开课答案{
公共int Id{set;get;}
公共字符串应答文本{set;get;}
公共虚拟问题{get;set;}
公共虚拟ICollection人员{get;set;}
}
}
您不能只将C#对象传递给JS并将其发回

你应该:

  • 将对象转换为JSON并将其传递给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) {       }
标记:

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) {       }
控制器:

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) {       }
更新:

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) {       }
由于类之间的循环引用,无法正确序列化测量实体。因此,您在这里几乎没有选择:

  • 使用[JsonIgnore]属性忽略反向引用。(因此,您应该使用此属性标记Question类内的Survey属性、Answer类内的Question属性等等)请记住,这些字段将不会序列化为JS并反序列化回C#objects
  • 为序列化创建不带循环引用的单独模型,并在转换为JSON时使用它

    • 你做错了

      基本上,当您进行
      @survey
      时,您看到的是服务器端代码。在客户端,这个
      @survey
      ,它是强类型clr类的一个实例,被转换为字符串,您知道当您将和object转换为字符串时会发生什么,您可以在字符串中得到它的类型,即

      @survey.ToString() == "WebApplications2.Models.Survey"
      
      显然,这是错误的,因为按钮标记的标记最终实际上变成:

      <button class='mybutton' type='button' 
               onclick="javascript:SubmitClick(@Model.Item1.Id, 
                                           WebApplications2.Models.Survey);">
              Save Survey
      </button>
      
      并在javascript中使用此隐藏变量

      i、 e


      发回
      @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; }
      }
      
      @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>    
      }
      
      @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>
      }
      
      公共类人物
      {
      公共int Id{set;get;}
      }
      公营班级调查
      {
      公共int Id{set;get;}
      公共虚拟ICollection问题{set;get;}
      }
      公开课问题
      {
      公共int Id{set;get;}
      公共字符串QuestionText{set;get;}
      公共虚拟ICollection答案{set;get;}
      public int SelectedAnswerId{set;get;}//请注意,我将其更改为int-not-string
      }
      公开课答案
      {
      公共int Id{set;get;}
      公共字符串应答文本{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 });
      }
      
      public ActionResult Index()
      {
      var person=新的人{Id=1};
      var调查=新调查
      {
      Id=12,
      问题=新列表
      {
      新问题
      {
      Id=34,
      QuestionText=“你最喜欢的语言是什么?”,
      答案=新列表
      {
      新答案{Id=56,AnswerText=“A#”},
      新答案{Id=57,AnswerText=“B#”},
      新答案{Id=58,AnswerText=“C#”}
      }
      }
      }
      };
      var模型=新元组(个人,新列表{survey});
      返回视图(模型);
      } 
      [HttpPost]
      公共行动结果提交(int personId,调查)
      {
      返回Json(新的{success=true});
      }
      
      Index.cshtml

      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; }
      }
      
      @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>    
      }
      
      @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>
      }
      
      @模型元组
      @{
      ViewBag.Title=“Index”;
      }
      调查
      @{int i=1;}
      @foreach(模型项目2中的var调查)
      {
      使用(Html.BeginForm())
      {
      调查@(i++)
      @Html.HiddenFor(x=>survey.Id)
      @EditorFor(x=>survey.Questions)
      保存调查
      }
      }
      @节脚本
      {
      $(“.mybutton”)。单击(函数(){
      var personId=“@Model.Item1.Id”;
      var-survey=$(this).closest(“form”).serialize();
      var数据=调查+“&personId=”