Я наконец решил эту проблему с помощью JavaScript. Без Blazor вы не можете использовать чистый ASP.Net Razor для достижения этой цели. Код JavaScript, который я написал, выглядит следующим образом:
<div id="otherProperties">
<div id="otherProperty-0">
<i id="deleteProperty-0" class="material-icons" onclick="RemoveProperty(id)">delete</i>
<input id="otherPropertyKey-0" name="propertyKey-0" type="text" placeholder="Property name"/>
<input id="otherPropertyValue-0" name="propertyValue-0" type="text" placeholder="Property value"/>
<i id="addProperty" class="material-icons" onclick="AddProperty()"></i>
</div>
Тогда код JavaScript будет таким
var idCounter = 1;
var keyValuePairArray = ['0'];
function AddProperty() {
if(document.getElementById('deleteProperty-'.concat(idCounter-1)) !== null) {
document.getElementById('deleteProperty-'.concat(idCounter - 1)).style.visibility = 'visible';
}
var newProperty = GenerateOtherProperty(idCounter);
document.getElementById('otherProperties').insertAdjacentHTML('beforeend',newProperty);
keyValuePairArray.push(idCounter.toString());
idCounter = idCounter +1 ;
}
function RemoveProperty(id) {
//from id extract the number
var propId = id.toString().split('-')[1];
document.getElementById('otherProperty-'.concat(propId)).remove();
var index = keyValuePairArray.indexOf(propId.toString(),0);
if(index > -1){
keyValuePairArray.splice(index,1);
}
}
function KeyValuePair(key,value) {
this.key = key;
this.value = value;
}
function GetKeyValueInputBoxes() {
var otherProps = [];
for (i =0; i < keyValuePairArray.length; i++){
var key = GetElement('otherPropertyKey-'.concat(keyValuePairArray[i])).value;
var value = GetElement('otherPropertyValue-'.concat(keyValuePairArray[i])).value;
var kvp = new KeyValuePair(key,value);
otherProps.push(kvp);
}
return otherProps;
}
/**
* @return {string}
*/
function GenerateOtherProperty (counter) {
var rawOtherProperty = ' <div id="otherProperty">\n' +
' <i id="deleteProperty" class="material-icons" onclick="RemoveProperty(id)">delete</i>\n' +
' <input id="otherPropertyKey" name="propertyKey" type="text" placeholder="Property name"/>\n' +
' <input id="otherPropertyValue" name="propertyValue" type="text" placeholder="Property value"/>\n' +
' <i id="addProperty" class="material-icons" onclick="AddProperty()"></i>\n' +
' </div>';
var freshProp = new DOMParser().parseFromString(rawOtherProperty,"text/html");
freshProp.getElementById("otherProperty").id = 'otherProperty-'.concat(counter);
freshProp.getElementById("deleteProperty").id = 'deleteProperty-'.concat(counter);
freshProp.getElementById("otherPropertyKey").id = 'otherPropertyKey-'.concat(counter);
freshProp.getElementById("otherPropertyValue").id = 'otherPropertyValue-'.concat(counter);
return freshProp.body.innerHTML;
}
Итак, используя JS, мы контролируем поведение пользовательского интерфейса и собираем значения в полях. Мы преобразуем данные в объект JSON и разместим их как необработанное тело запроса на нашем контроллере Web API сзади.
[HttpPost]
[Route("api/event")]
public IActionResult ProcessForm([FromBody] JObject jsonRawBody)
{
var jsonData = JsonConvert.DeserializeObject<Event>(jsonRawBody.ToString());
// process jsonData
}
Где модель события:
public class Event
{
[JsonProperty("otherKVP")]
public IList<KeyValuePair<string,string>> OtherProperties { get; set; }
}