我已经遇到了一段时间的问题,而且我不确定如何绕过它或如何解决它。我对Ajax非常陌生,所以试图找到我的问题的例子已经不足。
我的问题是我需要将模型发送到控制器,以便在用户向服务器提交之前验证/验证服务器端的特定参数。这基本上是条件验证服务器端,参数A仅在参数B为假时才需要,所以当用户在点击提交时未能在参数A中有文件时,Ajax调用将发送服务器端验证以查看用户是否是允许提交空文件值。
根据我的阅读,我无法发送与视图模型不同的模型。因为我使用的是局部视图,所以主视图的视图模型仍然是必须通过ajax调用发送到控制器的模型,即使我想发送嵌套模型。 (请告诉我,如果这是错的,我已经阅读了很多关于这个主题的代码示例和问题)
然而,它变得有点复杂,因为视图模型由带有列表的嵌套模型组成,嵌套模型中有更多嵌套模型和模型列表。
以下是主视图中的当前Ajax调用
<script type="text/javascript">
$(function () {
$("#test").change(function () {
var values =
{
XmlValue: $("#test").val(),
}
$.ajax({
type: 'POST',
url: '/TestSuites/UploadValidation',
data: JSON.stringify(values),
contentType: 'application/json; charset=utf-8',
dataType: "json",
success: function (data) {
alert(data);
}
});
});
});
</script>
以下是视图模型的布局。
AddTestSuiteViewModel (Main viewmodel)
- List<AddTestStepDisplayModel>
- AddTestStepDisplayModel
- AddTestStepParameterModel (PartialView view model)
- List<AddXmlParameterModel>
- AddTestStepXmlParameterModel
这是有问题的AddTestStepXmlParameterModel
public class AddTestStepXmlParameterModel
{
public string ParameterName { get; set; }
public string Description { get; set; }
[AssertThat("BindingExists == false", ErrorMessage = "An Xml file is required to save this test step")]
[FileExtensions(Extensions = "xml", ErrorMessage = "Specify an XML file.")]
public HttpPostedFileBase XmlValue { get; set; }
public bool BindingExists { get; set; }
}
以下是嵌套顺序的其他模型
AddTestSuiteViewModel
public class AddTestSuiteViewModel
{
public AddTestSuiteViewModel()
{
this.AddTestSuiteModel = new AddTestSuiteModel();
this.IsTestSuiteComplete = false;
}
public AddTestSuiteViewModel(TestSuite testSuite)
{
ParameterValidator.ValidateObjectIsNotNull(testSuite, "testSuite");
this.TestSuiteId = testSuite.TestSuiteId;
this.AddTestSuiteModel = new AddTestSuiteModel();
this.AddTestSuiteModel.TestSuiteName = testSuite.Name;
this.AddTestStepModel = new AddTestStepModel(testSuite);
this.AddTestStepModel.PreStepSequenceNumber = 1;
this.AddTestStepModel.MainStepSequenceNumber = 1;
this.PreTestSteps = new List<AddTestStepDisplayModel>();
this.MainTestSteps = new List<AddTestStepDisplayModel>();
this.DefinedTestStepNames = new List<string>();
this.DefinedTestStepIds = new List<int>();
}
public int TestSuiteId { get; set; }
public AddTestSuiteModel AddTestSuiteModel { get; set; }
public AddTestStepModel AddTestStepModel { get; set; }
public List<AddTestStepDisplayModel> PreTestSteps { get; set; }
public List<AddTestStepDisplayModel> MainTestSteps { get; set; }
public List<string> DefinedTestStepNames { get; set; }
public List<int> DefinedTestStepIds { get; set; }
}
AddTestStepDisplayModel
public class AddTestStepDisplayModel
{
public AddTestStepDisplayModel()
{
this.IfOtherTestStepsAreDependentOnTestStep = false;
this.DependencyViewModel = new DependencySelectViewModel();
}
public int TestStepId { get; set; }
public string TestStepName { get; set; }
public AddTestStepParametersModel AddTestStepParametersModel { get; set; }
}
AddTestStepParametersModel
public class AddTestStepParametersModel
{
public AddTestStepParametersModel()
{
this.TestStepXmlParameterDefinitions = new List<TestStepParameterDefinition>();
this.AddTestStepXmlParameterModels = new List<AddTestStepXmlParameterModel>();
}
public List<TestStepParameterDefinition> TestStepXmlParameterDefinitions { get; set; }
public List<AddTestStepXmlParameterModel> AddTestStepXmlParameterModels { get; set; }
public string SelectedTestStepValue { get; set; }
public int XmlParameterCount()
{
return this.TestStepXmlParameterDefinitions.Count();
}
}
然后转到AddTestStepXmlParameterModel列表。
我需要一个Ajax调用,它使用一个包含两个值的AddTestStepXmlParameterModel构建复杂的主视图模型。如果有人有他们可以分享的任何代码,或者解决类似问题的解决方案/指南,我绝对不知道如何做到这一点。
谢谢,这是一个很长的问题。
编辑:以下是视图和控制器页面
[HttpPost]
public JsonResult UploadValidation(AddTestStepXmlParameterModel model)
{
return Json(JsonRequestBehavior.AllowGet);
}
主视图
@model Models.AddTestSuiteViewModel
@{
ViewBag.Title = "Manage Test Suite";
}
<h1>Manage Test Suite</h1>
<head>
<script src="~/Scripts/jquery-3.1.0.js"></script>
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
<script src="~/Scripts/expressive.annotations.validate.js"></script>
</head>
@Html.Partial("MainTestStepTable", Model)
<script type="text/javascript">
$(function () {
$("#test").change(function () {
var values =
{
XmlValue: $("#test").val(),
}
$.ajax({
type: 'POST',
url: '/TestSuites/UploadValidation',
data: JSON.stringify(values),
contentType: 'application/json; charset=utf-8',
dataType: "json",
success: function (data) {
alert(data);
}
});
});
});
</script>
部分视图
@model Models.AddTestSuiteViewModel
@{
int i = 0;
}
@foreach (var testStep in Model.MainTestSteps)
{
@using (Html.BeginForm("EditTestStep", "TestSuites", FormMethod.Post, new {enctype = "multipart/form-data"}))
{
<div>
@Html.Partial("AddParameters", testStep.AddTestStepParametersModel)
</div>
}
添加参数部分视图
@model Models.AddTestStepParametersModel
for (int k = 0; k < Model.XmlParameterCount(); k++)
{
<div>
<br />
@Html.HiddenFor(m => m.AddTestStepXmlParameterModels[k].ParameterName, new { @Value = Model.TestStepXmlParameterDefinitions[k].Name })
@Html.HiddenFor(m => m.AddTestStepXmlParameterModels[k].Description, new { @Value = Model.TestStepXmlParameterDefinitions[k].Description })
@Html.HiddenFor(m => m.AddTestStepXmlParameterModels[k].ParameterType, new { @Value = Model.TestStepXmlParameterDefinitions[k].ParameterType })
@Html.LabelFor(m => m.AddTestStepXmlParameterModels[k].ParameterName, "Parameter Name: " + @Model.TestStepXmlParameterDefinitions[k].Name, htmlAttributes: new { @class = "control-label" })
<br />
<div class="col-md-4">
<div class="form-group">
@Html.EditorFor(m => Model.AddTestStepXmlParameterModels[k])
</div>
</div>
<div class="col-md-3">
<div class="form-group">
@Html.LabelFor(m => m.ParameterRepositoryDataCheckViewModelList[k].RepositoryDataExist, "Data Exist in Database?")
@Html.CheckBoxFor(m => m.ParameterRepositoryDataCheckViewModelList[k].RepositoryDataExist, new { disabled = "disabled" })
</div>
</div>
</div>
}
模特的编辑模板
@model Models.AddTestStepXmlParameterModel
<div>
@Html.TextBoxFor(m => Model.XmlValue, new { type = "file", @class = "btn btn-default btn-file", style = "color:transparent", onchange = "this.style.color = 'black'", id= "test" })
@Html.ValidationMessageFor(m => Model.XmlValue, "", new {@class = "text-danger"})
</div>