ASP.NET MVC - параметр контроллера не собирается из формы? - PullRequest
1 голос
/ 19 мая 2009

У нас сейчас проблема с контроллером; контроллер выглядит так:

public class AccountsController:Controller {
    public ActionResult List(int? page, int? pageSize, string keywords) {...}
}

Мы публикуем эту страницу через jquery:

$.post("/myapp/Accounts/List",
       {"page":0,"pageSize":10,"keywords":"asdf"}, 
       updategrid,
       "json");
...
function updategrid(result) {...}

Внутри действия: Request.Form ["ключевые слова"] == "asdf", но ключевые слова == "" и вот я в недоумении. Почему ключевые слова не имеют значение, которое мы хотим?

Ответы [ 7 ]

1 голос
/ 01 июля 2009

цитируемый ответ предоставляется в качестве комментария от Марка Уорта ...

Как твой контроллер? инстанцирован? У меня была эта проблема, и я обнаружил, что это был мой SpringControllerFactory создает мой контроллеры как синглтоны (а значит и всегда использовал значения из первый запрос). - Марк Уорт 19 мая в 8: 19

Вот и все! Мой контроллер был зарегистрирован как синглтон в мой Виндзорский контейнер, так что мой WindsorControllerFactory вернул синглтон. - Билл Барри 19 мая в 18: 14

0 голосов
/ 18 июня 2009
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
    public class JsonParametersFilter : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            string contentType = filterContext.HttpContext.Request.ContentType;

            if (string.IsNullOrEmpty(contentType))
                return;

            if (!contentType.Contains("application/json"))
                return;

            string paramValue;

            using (var reader = new StreamReader(filterContext.HttpContext.Request.InputStream))
                paramValue = reader.ReadToEnd();

            var serializer = new JavaScriptSerializer();
            var rawResult = (IDictionary<string, object>)serializer.DeserializeObject(paramValue);

            var keys = new List<string>(filterContext.ActionParameters.Keys);

            foreach (var key in keys)
            {
                object value = null;

                if (rawResult.TryGetValue(key, out value))
                {
                    filterContext.ActionParameters[key] = value;
                }
            }
        }
    }

Это попытается заполнить все значения параметров из inputtream.

0 голосов
/ 19 мая 2009

Это очень странно, потому что код на моей машине работает. Что происходит, когда вы запрашиваете URL непосредственно из браузера (без вызова jQuery .post ()), например так:

/myapp/Accounts/List?page=0&pageSize=10&keywords=asdf

Создает запрос GET (вместо запроса POST, сгенерированного методом jQuery .post (), но параметры метода действия должны быть заполнены).

В целях отладки вы можете изменить метод действия на что-то вроде:

public ActionResult List(int? page, int? pageSize, string keywords)
{
     return Content(String.Format("page = {0}, pageSize = {1}, keywords = {2}",
                    page, pageSize, keywords));
}

Если это работает, следующим шагом будет проверка вашего вызова jQuery с чем-то вроде (изменение формата возвращаемых данных с JSON на текст):

 $.post('/myapp/Accounts/List',
        { 'page' : 0, 'pageSize' : 10, 'keywords' : 'asdf' },
        function(result) {
           alert(result);
        },
        'text');

Все выше сработало правильно для меня, поэтому, если я что-то упустил ... Я озадачен, почему это не сработало для вас? Где я ошибся?

0 голосов
/ 19 мая 2009

Поскольку указанный выше атрибут работает, вы проверили сравнение содержимого коллекции HttpContext.Request.Form с объектом MVC-Binder-Bound FormCollection. Кажется, что есть разница между двумя наборами. Кроме того, попробуйте другие способы доступа к FormCollection - Get (), GetValue () ... проверьте AllKeys для ключа, который вас интересует ???

Кроме того, что касается идеи регистрации маршрута ...

Если у вас нет зарегистрированного маршрута myApp / Accounts / List / {page} / {pageSize}, а размер страницы все еще проходит, значит, нет необходимости регистрировать myApp / Accounts / List / {страница} / {pageSize} / {ключевые слова} либо маршрут.

0 голосов
/ 19 мая 2009

Используя этот атрибут:

[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
public class StringParamFilterAttribute:ActionFilterAttribute {
    public string Param { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext) {
        filterContext.ActionParameters[Param] = filterContext.HttpContext.Request[Param];
    }
}

Мне удалось добавить атрибут в действие, чтобы передать этот параметр методу:

[StringParamFilter(Param="keywords")]
public ActionResult List(int? page, int? pageSize, string keywords) {...}

и теперь ключевые слова имеют желаемое значение

0 голосов
/ 19 мая 2009

Если вы публикуете значения, вы можете просто использовать FormCollection ..

public class AccountsController:Controller {
public ActionResult List(int? page, FormCollection collection) {

  string keywords=collection["keywords"];
  ....
}

}

Кроме того, для сообщения вы можете добавить идентификатор к URL-адресу и поместить другие параметры в json. Я также не считаю необходимым указывать имена ваших свойств в кавычках в формате json.

$.post("/myapp/Accounts/List/"+page,
   {pageSize:10,keywords:"asdf"}, 
   updategrid,
   "json");

... функция updategrid (результат) {...}

... или, как предлагали другие, вы можете создать маршрут, который имеет все возможные параметры ..

0 голосов
/ 19 мая 2009

Разве вы не хотите передать значения в URL и позволить маршрутизации MVC позаботиться о передаче значений? Не передать как фактические переменные?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...