Ваша проблема в том, что частичный renders html основан на одном объекте AdminProductDetailModel
, но вы пытаетесь отправить обратно коллекцию. Когда вы динамически добавляете новый объект, вы продолжаете добавлять повторяющиеся элементы управления, которые выглядят как (это также создает недопустимый html из-за дубликатов атрибутов
id
), где они должны быть ,
и т. Д. для привязки к коллекции на обратной стороне.
DefaultModelBinder
требовалось, чтобы индекс для элементов коллекции начинался с нуля и был последовательным, или что значения формы включают в себя Index=someValue
, где индекс someValue
(например, . Это подробно объясняется в статье Фила Хаака «Связывание модели с списком» . Использование подхода Index обычно лучше, поскольку оно также позволяет удалять элементы из списка (в противном случае было бы необходимо переименовать все существующие элементы управления, чтобы индекс был последовательным).
Два возможных подхода к вашей проблеме.
Вариант 1
Используйте BeginItemCollection для вашего частичного представления. Этот помощник отобразит скрытый ввод для значения Index
на основе идентификатора GUID. Это нужно как в частичном представлении, так и в где вы визуализируете существующие элементы. Ваша часть будет выглядеть примерно так:
@model IKLE.Model.ProductModel.AdminProductDetailModel
@using(Html.BeginCollectionItem())
{
@Html.LabelFor(model => model.fkConfigChoiceCategorySizeId)
@Html.DropDownListFor(model => model.fkConfigChoiceCategorySizeId, Model.sizeList, "--Select Size--")
@Html.ValidationMessageFor(model => model.fkConfigChoiceCategorySizeId)
....
}
Вариант 2
Вручную создайте элементы html, представляющие новый объект с помощью «фальшивого» индексатора, поместите их в скрытый контейнер, затем в событие кнопки «Добавить», клонирование html, обновление индексаторов и значение индекса и добавление клонированных элементов в DOM. Чтобы убедиться, что html верен, создайте один объект по умолчанию в цикле for
и проверьте созданный html. Пример этого подхода показан в в этом ответе
Обратите внимание на использование индексатора «поддельных», чтобы предотвратить его привязку к post back («#» и [%]]
Преимущество варианта 1 состоит в том, сервер при каждом добавлении нового элемента. Преимущество варианта 2 заключается в том, что все его клиентская сторона, но если вы внесете какие-либо изменения в вашу модель (например, добавьте атрибут проверки в свойство), вам также потребуется вручную обновить html, что упростит обслуживание.
Наконец, если вы используете проверку на стороне клиента (jquery-validate-unobtrusive.js), тогда вам нужно повторно проанализировать валидатор каждый раз, когда вы добавляете новые элементы в DOM, как описано в , этот ответ .
$('form').data('validator', null);
$.validator.unobtrusive.parse($('form'));
И, конечно, вам нужно изменить метод POST, чтобы принять коллекцию
[HttpPost]
public ActionResult AddDetail(IEnumerable model)
{
....
}
, если вы выбрали один и тот же дважды, удалите его из вариантов для раунда:
import random
hex_digits = set('0123456789ABCDEF')
result = ""
pick_from = hex_digits
for digit in range(12):
cur_digit = random.sample(hex_digits, 1)[0]
result += cur_digit
if result[-1] == cur_digit:
pick_from = hex_digits - set(cur_digit)
else:
pick_from = hex_digits
print(result)
Поскольку название упоминает генераторы. Вот как указано выше:
import random
hex_digits = set('0123456789ABCDEF')
def hexGen():
while True:
result = ""
pick_from = hex_digits
for digit in range(12):
cur_digit = random.sample(hex_digits, 1)[0]
result += cur_digit
if result[-1] == cur_digit:
pick_from = hex_digits - set(cur_digit)
else:
pick_from = hex_digits
yield result
my_hex_gen = hexGen()
counter = 0
for result in my_hex_gen:
print(result)
counter += 1
if counter > 10:
break
Результаты:
1ECC6A83EB14
D0897DE15E81
9C3E9028B0DE
CE74A2674AF0
9ECBD32C003D
0DF2E5DAC0FB
31C48E691C96
F33AAC2C2052
CD4CEDADD54D
40A329FF6E25
5F5D71F823A4
Вы также можете изменить цикл while, чтобы получить определенное количество из них на основе пройденного числа в функцию.
Вы можете использовать генератор, итерирующий окно над строками, которые дает текущая реализация. STH. например (hex_str[i:i + 3] for i in range(len(hex_str) - window_size + 1))
Используя len
и set
, вы можете подсчитать количество разных символов в фрагменте. Хотя в вашем примере было бы проще просто сравнить все 3 символа.
Вы можете создать массив от 0 до 255 и использовать random.sample с вашим списком, чтобы получить ваш список
Я интерпретирую этот вопрос так: «Я хочу построить таблицу радуги, повторяя все строки, которые обладают следующими качествами: строка имеет длину 12, содержит только символы 0-9 и AF, и она никогда не имеет тот же символ появляется три раза подряд. "
def iter_all_strings_without_triplicates(size, last_two_digits = (None, None)):
a,b = last_two_digits
if size == 0:
yield ""
else:
for c in "0123456789ABCDEF":
if a == b == c:
continue
else:
for rest in iter_all_strings_without_triplicates(size-1, (b,c)):
yield c + rest
for s in iter_all_strings_without_triplicates(12):
print(s)
Результат:
001001001001
001001001002
001001001003
001001001004
001001001005
001001001006
001001001007
001001001008
001001001009
00100100100A
00100100100B
00100100100C
00100100100D
00100100100E
00100100100F
001001001010
001001001011
...
Обратите внимание, что будет выведено значение в несколько сотен терабайт, поэтому вы можете 't экономя много места по сравнению с тем, чтобы просто сохранить каждую строку, три раза или нет.
import string, random
source = string.hexdigits[:16]
result = ''
while len(result) < 12 :
idx = random.randint(0,len(source))
if len(result) < 3 or result[-1] != result[-2] or result[-1] != source[idx] :
result += source[idx]
00A300BF8911
, который имеет четыре нуля?
– Kevin
13 July 2018 в 16:13
Вы можете извлечь случайную последовательность из списка из двух шестнадцатиричных цифр:
digits = list('1234567890ABCDEF') * 2
random.shuffle(digits)
hex_number = ''.join(digits[:12])
Если вы хотите разрешить более короткие последовательности, вы можете также рандомизировать их и заполнить пробелы нулями.
import random
digits = list('1234567890ABCDEF') * 2
random.shuffle(digits)
num_digits = random.randrange(3, 13)
hex_number = ''.join(['0'] * (12-num_digits)) + ''.join(digits[:num_digits])
print(hex_number)
00A300BF8911
, который имеет четыре нуля?
– Kevin
13 July 2018 в 16:14
000000123456
, будет незаконным, даже если все нули произойдут от заполнения слева. Если моя интерпретация верна, я ожидаю, что должен быть дополнительный шаг, чтобы отфильтровать эти результаты.
– Kevin
13 July 2018 в 16:20
last_digit =
из моего последнего редактирования, потому что он не нужен (result[-1]
имеет последнюю цифру) – Zev 13 July 2018 в 16:32