ASP.NET MVC $.post вызов, возвращающий строку... нужна помощь с форматом для jqGrid

Я пытаюсь динамически заполнить раскрывающийся список для jqGrid, когда пользователь редактирует данные. У меня это в значительной степени работает, однако, есть одно значение в раскрывающемся списке "неопределенный". Я подозреваю, что это из-за способа отправки данных в сетку. Я использую ASP.NET MVC 2, и я получаю данные для раскрывающегося списка, используя jQuery следующим образом:

var destinations = $.ajax({ type:"POST",
                        url: '<%= Url.Action("GetDestinations", "Logger") %>',
                        dataType: "json",
                        async: false,
                        success: function(data) {

                         } }).responseText;

Теперь jqGrid хочет, чтобы значения выпадающего меню были отформатированы следующим образом:

value: "FE:FedEx; IN:InTime; TN:TNT"

Я использую StringBuilder, чтобы перебрать мою коллекцию и предоставить правильную строку, которую хочет jqGrid:

foreach (var q in query)
{
     sb.Append("ID:");
     sb.Append(q.Destination);
     sb.Append("; ");
}

Я возвращаю это из моего контроллера следующим образом:

return this.Json(sb.ToString());

Все это прекрасно, и я получаю все предметы, которые мне нужны для выпадающего списка, но есть дополнительный предмет (последний), который называется "неопределенный".

Я думаю, что проблема в том, что когда я отлаживаю в FireBug, результат для jqGrid выглядит так:

value: ""ID: One;ID: Two;ID: Three;ID: Four;ID: Five;""

Посмотрите, как есть два набора цитат. Это, вероятно, потому что, когда я говорю:

sb.ToString()

Вероятно, он генерирует кавычки, а затем jqGrid добавляет второй набор. Но я не на 100% в этом.

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

РЕШЕНИЕ:

Я решил это с помощью return ContentResult(sb.ToString();

Я хотел бы использовать метод dataUrl, как упомянул Олег, но пока что это не работает.

3 ответа

Решение

Если вы попытаетесь решить проблему только для jqGrid, вы можете выбрать другой путь.

Вы можете использовать dataUrl и buildSelect свойства editoptions или searchoptions вместо value имущество. Эти функции введены специально для использования в AJAX. DataUrl определяет предоставленные URL- адреса в форме, подобной

<select><option value="1">One</option> <option value="2">Two</option></select>

Если для вас легче вернуть результаты JSON с сервера, вам поможет пользовательская функция buildSelect. В качестве параметра он получает данные, отправленные с сервера, и должен вернуть строку <select><option>...</option></select>, В пути вы достигнете лучших результатов.

Если вы решили остаться на прежнем уровне, вы должны, по крайней мере, исправить свой код следующим

foreach (var q in query)
{
     if (sb.Length != 0)
         sb.Append(';');
     sb.Append(q.Destination); // instead of sb.Append("ID");
     sb.Append(':');
     sb.Append(q.Destination);
}

чтобы имеет "FedEx:FedEx;InTime:InTime;TNT:TNT" вместо "ID:FedEx; ID:InTime; ID:TNT; ",

ОБНОВЛЕНО: Вы попросили маленький пример. Давайте, например, вы можете получить все различные значения строк назначения как List<string> и название этого метода GetAllDestinations, Тогда ваше действие, используемое dataUrl, может выглядеть так

public JsonResult GetDestinationList() {
    List<string> allDestinations = GetAllDestinations();
    Json(allDestinations, JsonRequestBehavior.AllowGet);
}

Чтобы использовать это действие внутри editoptions или searchchoptions jqGrid, вы можете определить следующее

{ name: 'destinations', ditable: true, edittype:'select',
  editoptions: { dataUrl:'<%= Url.Action("GetDestinationList","Home") %>',
                 buildSelect: function(data) {
                     var response = jQuery.parseJSON(data.responseText);
                     var s = '<select>';
                     if (response && response.length) {
                         for (var i = 0, l=response.length; i<l ; i++) {
                             var ri = response[i];
                             s += '<option value="'+ri+'">'+ri+'</option>';
                         }
                     }
                     return s + "</select>";
                 }
                }
}

Если вы не хотите иметь действия, которые будут использоваться для HTTP GET, вы можете использовать Json(allDestinations); вместо Json(allDestinations, JsonRequestBehavior.AllowGet); в GetDestinationList действие, но добавьте в список опций jqGrid дополнительную опцию

ajaxSelectOptions: { type: "POST" }

ОБНОВЛЕНО 2: Ответ уже старый. Тем временем код jqGrid где buildSelect будет называться был изменен. Теперь buildSelect будет использоваться внутри success обработчик jQuery.ajax (см. здесь) вместо complete обработчик перед (см. пост и пост, например). Так что в текущей версии jqGrid строка

var response = jQuery.parseJSON(data.responseText);

не нужен data как правило, анализируются данные JSON и поэтому строки

                 buildSelect: function(data) {
                     var response = jQuery.parseJSON(data.responseText);

в приведенном выше коде можно заменить на

                 buildSelect: function(response) {

Это еще одна альтернатива

[Метод Контроллера]

  [HttpGet]
    public ActionResult SchoolList()
    {
        //Get Schools
        var qry = SchoolManager.GetAll();

        //Convert to Dictionary
        var ls = qry.ToDictionary(q => q.SchoolId, q => q.Name);

        //Return Partial View
        return PartialView("_Select", ls);
    }

[_Выбрать частичное представление]

@model Dictionary<int, string>
<select>
<option value="-1">--select--</option>
@foreach(var val in Model)
{
    <option value="@val.Key.ToString()">@val.Value</option>
}

[Страница с jqGrid]

{ name: 'SchoolId', index: 'SchoolId', align: 'left', editable: true, edittype: 'select', editoptions: { dataUrl: '@Url.Action("SchoolList")' }, editrules: { required: true} },

Надеюсь, это сэкономит кому-то часы поиска в Google!

Я считаю, что проблема с цитатой устранена

$.ajax({ type:"POST",
         url: '<%= Url.Action("GetDestinations", "Logger") %>',
         dataType: "json",
         async: false,
         success: function(data) {
           destinations = data.value;
         }
      });

Это должно работать, данные в этом случае были преобразованы из json, поэтому значение будет преобразовано в строку без двойных кавычек.

Если это не сработает, измените оператор return так:

return "{ value : """+sb.ToString()+""" }";

Yay Linq (этого не будет ; что я думаю, это ваша проблема.)

  (From q In query.AsEnumerable
   select "ID: "+q.Destination).join(";");

(возможно, опечатки я не проверял)

Другие вопросы по тегам