Удаленная проверка MVC3 поля в списке - PullRequest
2 голосов
/ 21 января 2012

По какой-то причине, когда я пытаюсь удаленно проверить примитивное свойство внутри массива в моей модели, значение свойства не передается в качестве параметра.

Например, когда вызывается мой метод удаленной проверки (UniqueItemNo), строковый параметр "id" всегда равен нулю. Если бы я должен был выполнить проверку на CartNumber вместо ItemNumber, параметр передается правильно.

Контроллер

public class HomeController : Controller
{
    public ActionResult Index()
    {
        CartModel cart = new CartModel();
        cart.Items.Add(new ItemModel() { ItemNumber = "12345" });
        return View(cart);
    }

    [HttpPost]
    public JsonResult UniqueItemNo(string id)
    {
        /** Do Work **/
        return null;
    }
}

Модель

public class ItemModel
{
    [Remote("UniqueItemNo", "Home", HttpMethod="POST")]
    public string ItemNumber { get; set; }
}

public class CartModel
{
    public CartModel()
    {
        Items = new List<ItemModel>();
    }

    public List<ItemModel> Items { get; set; }
    public string CartNumber { get; set; }
}

View

@{
    ViewBag.Title = "Home Page";
}

<h2>@ViewBag.Message</h2>
@using(Html.BeginForm()) {
    <p>
        @for(int i = 0; i < Model.Items.Count; i++)
        {
            @Html.TextBoxFor(m => m.Items[i].ItemNumber);
            @Html.ValidationMessageFor(m => m.Items[i].ItemNumber);                                    
        }
    </p>
}

Ответы [ 4 ]

6 голосов
/ 21 ноября 2012

только что решил ту же проблему. так что для моего типа людей, которые будут иметь эту проблему в будущем, вот решение

вот основная причина.

когда вы делаете @Html.TextBoxFor(x=>x.m.Items[i].ItemNumber) он выводит что-то вроде этого

<input type=text value='value' name='items[index].ItemNumber' ...

и затем добавляет другие валидации, такие как атрибуты data- * для валидации. например URL-адрес удаленной проверки, URL-адрес удаленного доступа и т. д.

теперь, когда форма была проверена, она запрашивала удаленный URL с данными, такими как key = xxx [1] .propertyname

и это нельзя назначить одной переменной в методе удаленного действия, которая получит это свойство.

если вы измените аргументы действия на что-то подобное, то это будет работать

 public JsonResult UniqueItemNo(list<string> propertyname)

и даже в этом случае вы не гарантированы, так как для этого требуется, чтобы индекс параметров начинался с 0 и без пробелов. поэтому xxx [1] .ItemNumber никогда не будет отображен.

единственное оставшееся решение - получить имя свойства из строки запроса и сопоставить его с требуемой переменной. как это

    if(Request.QueryString.AllKeys.FirstOrDefault(p => p.ToLower().Contains("propertyname"))!=null)
    {
                     propertyname = Request.QueryString[Request.QueryString.AllKeys.First(p => p.ToLower().Contains("propertyname"))];
}

будет искать и отображать необходимые переменные.

надеюсь, это поможет

1 голос
/ 16 января 2014

Я надеюсь, что вы уже нашли ответ, но в случае, если вы этого не сделали, попробуйте это:

[HttpPost]
public JsonResult UniqueItemNo()
{
    var itemNumber = Request.Form[Request.Form.AllKeys.First(p => p.Contains("ItemNumber"))];

    /** Do Work **/
    return Json(true);
}

Обратите внимание, что ответ @Mamoon ur Rasheed был почти правильным, но, поскольку вы используете POST,параметры будут внутри свойства Form, а не QueryString.

Дайте мне знать, если у вас все еще есть какие-либо проблемы, связанные с этим.

Кстати, вы должны использовать try / catch.Я написал это не для простоты.

0 голосов
/ 14 мая 2013

К сожалению, у вас нет поддержки для этого.

На стороне клиента удаленная проверка обрабатывается jquery.validate.unobtrusive.js, который говорит

...
$.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) {
    var paramName = appendModelPrefix(fieldName, prefix);
    value.data[paramName] = function () {
        return $(options.form).find(":input[name='" + escapeAttributeValue(paramName) + "']").val();
    };
});
...

, поэтому вы должны заметить, что для каждого дополнительного поля он создает только один параметр в строке запроса (или в форме, если вы публикуете). из-за этого ваш удаленный атрибут на стороне сервера должен выглядеть как

[Remote("UniqueItemNo", AdditionalFields = "ItemNumber[0],ItemNumber[1],...")]

факт, который вы не знаете во время разработки.

Вы можете использовать js hack и сохранить скрытое поле с именем ItemNumber и со значением составной список идентификаторов. на стороне сервера вы должны изменить тип массива ItemNumber на строку и разделить значения.

Надеюсь, это поможет, хотя прошло много времени с тех пор, как вы спросили.

0 голосов
/ 21 января 2012

Попробуйте изменить параметр в соответствии с моделью.Например:

    [HttpPost]
    public JsonResult UniqueItemNo(ItemModel itemModel)
    {
        // look at itemModel.ItemNumber...
        /** Do Work **/
        return null;
    }

Имя параметра ActionMethod можно по-прежнему начинать со строчной буквы (itemNumber вместо ItemNumber) в соответствии с обычными правилами кодирования.1009 * РЕДАКТИРОВАТЬ: Вы пытались кодировать View, как это?

@{
    ViewBag.Title = "Home Page";
}

<h2>@ViewBag.Message</h2>
        @foreach (var item in Items)
        {
           @using(Html.BeginForm()) {
              <p>
                 @Html.HiddenFor(m=>m.CartNumber)
                 @Html.TextBoxFor(m => item.ItemNumber);
                 @Html.ValidationMessageFor(m => item.ItemNumber);                                    
              </p>
           }
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...