ASP.NET MVC $ .post call retornando string… precisa de ajuda com format para jqGrid

Eu estou tentando preencher dinamicamente um menu suspenso para o jqGrid quando o usuário está editando dados. Eu tenho praticamente funcionando no entanto, há um valor na chamada suspensa “undefined”. Eu suspeito que isso é por causa da maneira como estou enviando os dados para a grade. Estou usando o asp.net MVC 2 e estou recebendo os dados para o dropdown usando jQuery assim:

var destinations = $.ajax({ type:"POST", url: '', dataType: "json", async: false, success: function(data) { } }).responseText; 

Agora, o jqGrid quer os valores para o dropdown formatado assim:

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

Eu estou usando o StringBuilder para iterar através da minha coleção e fornecer a string apropriada que o jqGrid deseja:

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

Eu retorno isso do meu controlador assim:

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

Isso tudo é swell e eu recebo todos os itens que preciso para o menu suspenso, mas há um item extra (o último) chamado “indefinido”.

Eu acho que o problema é quando eu depuro no FireBug, o resultado para o jqGrid se parece com isso:

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

Veja como existem dois conjuntos de cotações. Isto é provavelmente porque quando eu digo:

 sb.ToString() 

Provavelmente gera as aspas e, em seguida, o jqGrid adiciona um segundo conjunto. Mas eu não sou 100% disso.

Qual é a melhor maneira de lidar com isso? Qualquer conselho seria muito apreciado.

SOLUÇÃO:

Eu resolvi isso usando return ContentResult (sb.ToString ();

Eu gostaria de usar o método dataUrl como Oleg mencionou, mas ainda não está funcionando.

Se você tentar resolver o problema para o jqGrid só poderá escolher outro caminho.

Você pode usar as propriedades dataUrl e buildSelect de editoptions ou searchoptions em vez da propriedade value . Esses resources são introduzidos especialmente para o uso em AJAX. O dataUrl define os resultados fornecidos pelo URL na forma como

  

Se for mais fácil retornar resultados JSON do servidor, sua function customizada buildSelect ajudará. Como o parâmetro recebe o envio de dados do servidor e deve retornar a string . No caminho você alcançará melhores resultados.

Se você decidir ficar à sua maneira antiga, você deve pelo menos corrigir seu código para seguir

 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); } 

tem "FedEx:FedEx;InTime:InTime;TNT:TNT" vez de "ID:FedEx; ID:InTime; ID:TNT; " .

ATUALIZADO : Você pediu um pequeno exemplo. Deixe-nos, por exemplo, obter todos os valores diferentes das cadeias de destino como uma List e o nome deste Method é GetAllDestinations . Então, sua ação usada pelo dataUrl pode parecer

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

Para usar esta ação dentro de editoptions ou searchoptions do jqGrid você pode definir sobre o seguinte

 { name: 'destinations', ditable: true, edittype:'select', editoptions: { dataUrl:'< %= Url.Action("GetDestinationList","Home") %>', buildSelect: function(data) { var response = jQuery.parseJSON(data.responseText); var s = '"; } } } 

Se você não quer ter ações que sejam usadas por HTTP GET, você pode usar o Json(allDestinations); em vez de Json(allDestinations, JsonRequestBehavior.AllowGet); na ação GetDestinationList , mas adicione à lista de opções jqGrid uma opção adicional

 ajaxSelectOptions: { type: "POST" } 

ATUALIZADO 2 : A resposta já é antiga. Nesse ínterim, o código de jqGrid ao qual buildSelect será chamado foi alterado. Agora o buildSelect será usado dentro do manipulador de success do jQuery.ajax (veja aqui ) ao invés do manipulador complete antes (veja o post e o post por exemplo). Então na versão atual do jqGrid a linha

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

Não é necessário. Os data são tipicamente os dados JSON analisados ​​e, portanto, as linhas

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

no código acima pode ser substituído para

  buildSelect: function(response) { 

Esta é outra alternativa

[Método do controlador]

  [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); } 

[_Selecionar vista parcial]

 @model Dictionary  

[Página com jqGrid]

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

Espero que isso economize alguém horas de pesquisando!

O problema da citação é fixo dessa maneira eu acredito

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

Isso deve funcionar, os dados neste caso foram convertidos do json, então o valor será avaliado para uma string sem as aspas duplas.

Se isso não funcionar, altere a declaração de retorno para ficar assim:

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

Yay Linq (isso não terá o rastro ; que eu acho que é problema seu.)

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

(pode ter erros de digitação eu não testei)