Да, я знаю, что об этом спрашивали тысячу раз, но я искал и искал, и ни один из приведенных ответов, похоже, не дал правильного результата.
В основном результат, который я хочу, ниже.
{
"ResourceKey":"427693d6-16af-43a5-b6ff-89408cf460eb",
"ResourceCategory":"HierarchyLevelResource",
"Translations": [
{
"Translation": "English Hierarchy",
"CultureCode": "en-GB"
},
{
"Transation": "French Hierarchy",
"CultureCode": "fr-FR"
}
]
}
Но все ответы, похоже, вместо этого выводят следующее.
{
"ResourceKey": "427693d6-16af-43a5-b6ff-89408cf460eb",
"ResourceCategory": "HierarchyLevelResource",
"Translations[0].Translation": "English Hierarchy",
"Translations[0].CultureCode": "en-GB",
"Translations[1].Translation": "French Hierarchy",
"Translations[1].CultureCode": "fr-FR"
}
C# MVC отлично переводит первый, поскольку для меня это правильно структурированный JSON, во втором примере он не преобразует элементы «Переводы».
Кто-нибудь знает какие-либо библиотеки, которые правильно переводят данные формы? Я использовал следующее, которое отлично работает для всего остального, кроме массивов.
$.fn.serializeObject = function () {
var o = {};
var a = this.serializeArray();
$.each(a, function () {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
Обновлено: Для получения дополнительной информации моя модель ...
public class CustomLocalisationModel
{
public string ResourceKey { get; set; }
public string ResourceCategory { get; set; }
public List<CustomLocalisationDataModel> Translations { get; set; }
}
public class CustomLocalisationDataModel
{
public string CultureCode { get; set; }
public string Translation { get; set; }
}
И он помещается в форму в следующем синтаксисе Razor ...
@using (Html.BeginForm("Index", "Localisation", FormMethod.Post, new {id = "translationsForm", novalidate = "novalidate", @class = "form-horizontal group-border-dashed", style = "border-radius:0px;"}))
{
@Html.HiddenFor(model => model.ResourceKey)
@Html.HiddenFor(model => model.ResourceCategory)
for (var translationIndex = 0; translationIndex < Model.Translations.Count(); translationIndex++)
{
<div class = "form-group">
<label class = "col-sm-2 control-label">@Model.Translations[translationIndex].LocalisedLanguageName</label>
<div class = "col-sm-10">
@Html.TextBoxFor(model => Model.Translations[translationIndex].Translation, new { @class = "form-control", placeholder = PageLocaliser["PleaseEnterTranslation"].Value })
@Html.HiddenFor(model => Model.Translations[translationIndex].CultureCode)
</div>
</div>
}
<div class = "form-group">
<div class = "row xs-pt-15">
<div class = "col-xs-6"> </div>
<div class = "col-xs-6">
<p class = "text-right">
<button id = "btnSaveLocalisations" type = "submit" class = "btn btn-space btn-primary" onclick = "return SaveLocalisations();">@CommonLocaliser["SubmitLabel"]</button>
<button id = "btnCancel" data-dismiss = "modal" type = "submit" class = "btn btn-space btn-default" onclick = "return false;">@CommonLocaliser["CancelLabel"]</button>
</p>
</div>
</div>
</div>
}
Обновлено еще раз:
Добавлен используемый метод Javascript.
function SaveLocalisations() {
console.info(JSON.stringify($('#translationsForm').serializeObject()));
$.ajax({
type: "POST",
url: "@Url.Action("Index", "Localisation", new {area = string.Empty})",
data: JSON.stringify($('#translationsForm').serializeObject()),
dataType: "json",
timeout: 7000,
contentType: "application/json",
success: function(msg) {
$.gritter.add({
position: "top-right",
title: "@CommonLocaliser["Success"]",
text: "@PageLocaliser["UpdateSuccessMessage"].Value",
class_name: 'clean img-rounded',
time: 5000
});
$('#localisationPartial').modal('hide');
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
$.gritter.add({
position: "top-right",
title: "@CommonLocaliser["Failed"]",
text: "@PageLocaliser["UpdateFailedMessage"].Value",
class_name: 'clean img-rounded',
time: 5000
});
}
});
return false;
};
Первый вариант работает при тестировании через почтальона, второй - нет. При тестировании второй выполняет проекцию только с объектами ResourceKey и ResourceCategory, но не с объектами Translations. Однако с первым все работает отлично.
2-й действительно работает! (Вы, должно быть, пытаетесь переопределить параметр contentType по умолчанию. Второй создается с использованием (скажем) $('form').serialize() и будет правильно связываться с использованием contentType по умолчанию (т.е. 'application/x-www-form-urlencoded; charset=UTF-8')
Вы не показали, что такое SaveLocalisations(), но все, что вам нужно, это (с использованием jQuery) - $.post(yourUrl, $('#translationsForm').serialize(), function(response) { ... });
Думаю, теперь я понимаю, о чем вы говорите. Вместо того, чтобы явно устанавливать для сообщения Ajax значение JSON, фактически отправляйте его как сообщение формы, а не сообщение JSON. Сейчас протестирую: D
Я добавил метод SaveLocalisations.
Позвольте нам продолжить обсуждение в чате.
Если вам просто нужно передать Form data контроллеру, нет необходимости конвертировать FormData в Json, каково определение действия Index в Localisation. Для передачи модели из form-data вам необходимо изменить действие контроллера, например (CustomLocalisationModel model) или [FromForm](CustomLocalisationModel model). Вы не должны использовать [FromBody]. Попробуйте [FromForm] со 2-м от почтальона.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Есть ли какая-то конкретная причина, по которой вы хотите использовать 1-й вариант (2-й вариант по умолчанию и будет привязан к вашей модели - 1-й требует, чтобы вы отправляли данные как строковые и устанавливали параметр
contentType: 'application/json'