我正在开发一个小型测试床应用程序,您可以在该应用程序中为应用程序提供音符名称,符号和八度音,并且它会发出音符发出的频率。
我遇到了通过AJAX发送到服务器的JavaScript对象的问题。但是,它根本不会映射到操作上的类。
发件人代码是JavaScript的一部分:
$someContainer.on('click', '.raise-pitch', function (e) {
e.preventDefault();
var $line = $(this).parents('.item-line'),
// Cache GUI elements for this line. Not pertinent.
var data = {
'model': {
'NoteName': $noteName.val(),
'Sign': $noteSign.val(),
'Octave': $noteOctave.val()
},
'steps': 1
};
var dataString = JSON.stringify(data);
$.ajax({
type: 'POST',
url: '@Url.Action("AlterPitch", "Home")',
data: dataString,
async: true,
dataType: 'json',
success: function (result) {
// Unimportant things.
}
});
});
在data
对象中,您可以看到我有两件事:model
和steps
。这些步骤决定了我们改变音符的程度。我已经确认note name
,sign
和octave
的值正在将其转换为数据对象。 steps
是预先确定的。
然而,data
对象映射到C#端的ViewModel,如下所示:
public class NoteViewModel
{
public enum NoteSign
{
Natural,
Sharp,
Flat
}
public string NoteName { get; set; }
public NoteSign Sign { get; set; }
public int Octave { get; set; }
public float Frequency { get; set; }
private static readonly Dictionary<string, float> FrequencyLookup = new Dictionary<string, float>
{
{"C", 16.35f},
{"C#", 17.32f},
{"D", 18.35f},
{"D#", 19.45f},
{"E", 20.60f},
{"F", 21.83f},
{"F#", 23.12f},
{"G", 24.50f},
{"G#", 25.96f},
{"A", 27.50f},
{"A#", 29.14f},
{"B", 30.87f}
};
// Methods...not important for reasons below.
}
...它本身封装在一个独特的视图模型中:
public class AlterPitchViewModel
{
public NoteViewModel model;
public int steps;
public NoteViewModel AlterPitch()
{
model.ChangeStep(steps);
return model;
}
}
......或者至少它应该。我在控制器方法中设置了一个断点:
[HttpPost]
public ActionResult AlterPitch(AlterPitchViewModel model)
{
return Json(model.AlterPitch(), JsonRequestBehavior.AllowGet);
}
...但该模型为空,这导致NullReference
例外。
模型没有序列化到在此上下文中发送的对象。显然我还在做错事。 问题是......什么?
答案 0 :(得分:1)
您的HttpPost方法必须有一个唯一的参数,即ViewModel。我的建议:为每个帖子创建一个viewModel WebMethod 。
所以这里:
public class AlterPitchViewModel
{
public NoteViewModel note { get; set; };
public int Steps { get; set; };
}
并相应地调整您的Javascript。无需将您的javascript模型实例命名为ASP方法中的参数 - &gt;一个对象到达,只有一个参数可用,所以没有歧义。
答案 1 :(得分:1)
这种方法对我有用。
服务器端:
首先,创建ViewModel
public class TestViewModel
{
public string Id { get; set; }
public string Description { get; set; }
}
然后,在Controller中:
[HttpPost]
public ActionResult TestingViewModel(TestViewModel udata)
{
// Stuff.
}
客户端:
function CallTestingViewModel() {
// We create the javascript object based on the
// definition of our C# ViewModel class.
var udata = {
Id: 1,
Description: 'This is a test.'
};
// Calling the C# method via AJAX.
$.when(GenericAjaxCall('Home/TestingViewModel', false, udata)).then(function (result) {
// do stuff
});
}
// Return the AJAX call as a Promise Object
function GenericAjaxCall(controllerUrl, async, clientData) {
return $.ajax({
type: 'POST',
async: async,
url: controllerUrl,
data: JSON.stringify(clientData),
contentType: 'application/json;',
dataType: 'json'
});
}
希望它有所帮助。