【发布时间】:2014-04-08 19:04:37
【问题描述】:
警告:问题太长了!有很多设置可以解决我需要询问的问题。
所以,我正在做一个小型实验项目,因为我试图弄清楚 如果我可以在通过 AJAX 发送到服务器的模型上触发服务器端 MVC 验证.实验应用采用音符名称、符号和八度音阶来确定音符的频率。
我的观点很标准:
<div id='frequency-line-container'>
// By default, nothing...
</div>
<div id='new-line-interface'>
<p>
What note is sounding? <input type='text' id='note-name' maxlength='1' />
</p>
<p>
What sign is by the note?
<span>
@Html.RadioButton("note-sign", "natural", true, new {id="note-natural"})Natural
@Html.RadioButton("note-sign", "sharp", false, new {id="note-sharp"})Sharp
@Html.RadioButton("note-sign", "flat", false, new {id="note-flat"})Flat
</span>
<p>
<p>
What octave is the note sounding at? <input type='number' id='octave' maxlength='1' min='0' max='9' />
</p>
<a href='#' id='save-button'>Save</a>
</div>
在客户端,我设置了以下 JavaScript:
$(document).ready(function () {
var $frequencyLineContainer = $('#frequency-line-container'),
$saveLineButton = $('#save-line'),
$noteName = $('#note-name'),
$octave = $('#octave');
$saveLineButton.click(function (e) {
e.preventDefault();
var data = getLineData();
var $promise = getNewLinePromise(data, true);
$.when($promise)
.then(addLine);
});
function getLineData() {
var $noteSign = $('#note-sign-section input[type="radio"][name="note-sign"]:checked');
var model = {
'NoteName': $noteName.val(),
'NoteSign': $noteSign.val(),
'Octave': parseInt($octave.val())
};
return {
'model': model
};
}
function getNewLinePromise(data, async) {
return $.ajax({
type: 'POST',
url: '/Home/AddFrequencyLine/',
contentType: 'application/json',
data: data,
async: async
});
}
function addLine(result) {
$frequencyLineContainer.append(result);
}
});
...在服务器上,我的操作非常简单:
[HttpPost]
public void AddFrequencyLine(FrequencyLineViewModel model)
{
model.CalculateFrequency(); // Determines the frequency of a note by sign, name, and octave...
return Partial("_FrequencyLine", model);
}
目前为止课程的标准。 现在,事情变得有趣了。
如您所见,虽然我们的笔记名称字段仅限于单个字符,但他们可以输入无效的笔记名称;音符范围从 A 到 G。如果用户从 H 到 Z 输入任何内容,则这不是有效的音符,因此不应生成频率!实际上,注释名称字段旁边应该会出现一条红色的错误消息。
我的FrequencyLineViewModel 看起来像这样...
public enum NoteSign
{
Natural,
Sharp,
Flat
}
public class FrequencyLineViewModel : IValidatableObject
{
[Required]
public string NoteName { get; set; }
[Required]
public NoteSign NoteSign { get; set; }
[Required]
public int Octave { get; set; }
public Dictionary<string, float> FrequencyLookup = new Dictionary<string, float>{
// Each note from A0 to G#0 has an associated frequency. This lists 'em.
// A full listing of the frequency table is not salient to this question.
}
public IEnumerable<ValidationResult> Validate(ValidationContext context)
{
List<ValidationResult> results = new List<ValidationResult>();
byte asciiCode = (byte) (NoteName.ToUpper())[0];
if(asciiCode >= 72 // Between H and Z
&& asciiCode <= 90)
{
results.Add(new ValidationResult("(Invalid)", new []{"NoteName"}));
}
// Could add other validations here
return results;
}
}
到目前为止,在我的测试中,我已经修改了我的动作:
public void AddFrequencyLine(FrequencyLineViewModel model)
{
model.IsValid = ModelState.IsValid;
if (ModelState.IsValid)
{
model.CalculateFrequency();
return PartialView("_NoteRecord", model);
}
// Need to change this...but to what?
model.ErrorMessage = "Something is wrong!";
return model;
}
...但是我不知道如何最好地实现验证的成果。我在 model.IsValid 检查的修改操作中设置了一个断点,并发现在无效的情况下,例如空表单或来自 H-Z 的注释,它被正确标记为无效;相反,当输入有效表单时,它会按预期工作。但是,我对“正确工作”部分不感兴趣。无效状态让我受阻。
如果结果的 IsValid 属性为 false(仅在无效的代码路径上发生),我可以简单地返回错误消息,并在成功处理程序中使用 JavaScript 来确定放置它的位置。问题是,这违背了 success 处理程序的目的;真正发生的是错误状态。
所以,最后,我的问题:我正在尝试显示一些验证消息,但此设置不适合这样做。在不使用我的 JavaScript 成功处理程序的情况下,如何使这个基于 AJAX 的模型验证呈现验证消息?
编辑:这是一个问题的原因是因为我们的团队希望将尽可能多的业务逻辑保留在服务器上;我们正在努力实现“瘦客户端”设置。这意味着 JavaScript 将只负责 1) GUI 状态,2) 将数据汇集回服务器进行处理,以及 3) 从服务器接收数据以进行呈现。
【问题讨论】:
标签: javascript jquery ajax validation asp.net-mvc-4