2009-06-18 26 views
12

Ho una vista con una griglia che contiene elementi aggiunti a una workstation. L'utente può selezionare un elemento da un elenco a discesa e fare clic su un collegamento di azione che chiama un controller che aggiunge tale elemento alla workstation. Posso farlo funzionare leggendo l'oggetto FormCollection nell'azione Post del controller.ASP.NET MVC Passaggio dei dati dalla vista al controller

<p> 
    <% using(Html.BeginForm("AddItem", "Home")) { %> 
    <label for="ItemID">Item:</label> 
    <%= Html.DropDownList("ItemID", Model.ItemsList) %> 
    <%= Html.Hidden("WorkstationID", Model.Workstation.RecordID) %> 
    <input type="submit" value="Submit" /> 
    <% } %> 
</p> 

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult AddItem(FormCollection formValue) 
{ 
    long workstationId = Convert.ToInt64(formValue["WorkstationID"]); 
    long itemId = Convert.ToInt64(formValue["ItemID"]); 

    Workstation workstation = itilRepository.FindWorkstation(workstationId); 
    Item item = itilRepository.FindItem(itemId); 

    itilRepository.AddItem(workstation, item); 
    itilRepository.Save(); 

    return Content("Item added successfully!"); 
} 

Quello che voglio fare è essere in grado di presentare i due parametri del workstationId e ItemID al controller utilizzando Ajax.ActionLink ed avere il nuovo elemento che è stata aggiunta ottenere inserita nella rete . Sono il rendering griglia così:

<table> 
     <tr> 
     <th></th> 
     <th> 
     Name 
     </th> 
     <th> 
     Service Tag 
     </th> 
     <th> 
     Serial Number 
     </th> 
    </tr> 

    <% foreach (var item in Model.Items) { %> 

    <tr> 
     <td> 
     <%= Html.ActionLink("Edit", "ItemEdit", new { id = item.RecordID }) %> | 
     <%= Html.ActionLink("Details", "ItemDetails", new { id = item.RecordID })%> 
     </td> 
     <td> 
     <%= Html.Encode(item.Name) %> 
     </td> 
     <td> 
     <%= Html.Encode(item.ServiceTag) %> 
     </td> 
     <td> 
     <%= Html.Encode(item.SerialNumber) %> 
     </td> 
    </tr> 

    <% } %> 

</table> 

Il problema che ho è quando presento usando l'ActionLink non riesco a capire come passare nei parametri al controllore e come aggiornare la rete senza ricaricare la vista intera

Apprezzerei molto l'aiuto con questo o anche un collegamento a un tutorial che fa qualcosa di simile.

Grazie!

Questa è la versione funzionante, l'unico problema è che quando il controller restituisce la vista parziale che è tutto ciò che viene trasformato, la pagina effettiva è scomparsa.

<% using (Ajax.BeginForm("AddItem", null, 
     new AjaxOptions 
     { 
      UpdateTargetId = "ResultsGoHere", 
      InsertionMode = InsertionMode.Replace 
     }, 
     new { @id = "itemForm" })) 
{ %> 

    <label for="ItemID">Item:</label> 
    <%= Html.DropDownList("itemId", Model.ItemsList) %> 
    <%= Html.Hidden("workstationId", Model.Workstation.RecordID) %> 

    <a href="#" onclick="$('#itemForm').submit();">Submit</a> 

    <div id="ResultsGoHere"> 
     <% Html.RenderPartial("WorkstationItems", Model.Items); %> 
    </div> 

<% } %> 

Non è sicuro quale sia la causa, la sostituzione funzionava correttamente prima ma il controller non ha ottenuto il valore di discesa. Ora il controller sta ottenendo il valore ma la vista parziale che viene restituita sostituisce l'intera pagina.

Il metodo d'azione:

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult AddItem(string workstationId, string itemId) 
{ 
    long lworkstationId = Convert.ToInt64(workstationId); 
    long litemId = Convert.ToInt64(itemId); 

    Workstation workstation = itilRepository.FindWorkstation(lworkstationId); 
    Item item = itilRepository.FindItem(litemId); 

    IQueryable<Item> items = itilRepository.AddItem(workstation, item); 
    itilRepository.Save(); 

    return PartialView("WorkstationItems", items); 
} 

Questo è il codice HTML per la vista che fa tutto il lavoro:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<ITILDatabase.Models.WorkstationFormViewModel>" %> 

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> 
    Workstation Details 
</asp:Content> 
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> 

    <script src="/Scripts/MicrosoftAjax.js" type="text/javascript"></script> 
    <script src="/Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script> 
    <link type="text/css" href="/../Content/css/ui-lightness/jquery-ui-1.7.2.custom.css" rel="stylesheet" />  
    <script type="text/javascript" src="/../Content/js/jquery-1.3.2.min.js"></script> 
    <script type="text/javascript" src="/../Content/js/jquery-ui-1.7.2.custom.min.js"></script> 

    <h2> 
     Workstation Details</h2> 
    <fieldset> 
     <legend>Fields</legend> 
     <p> 
      Record ID: 
      <%= Html.Encode(Model.Workstation.RecordID) %> 
     </p> 
     <p> 
      Name: 
      <%= Html.Encode(Model.Workstation.Name) %> 
     </p> 
     <p> 
      Description: 
      <%= Html.Encode(Model.Workstation.Description) %> 
     </p> 
     <p> 
      Site: 
      <%= Html.Encode(Model.Workstation.Site.Name) %> 
     </p> 
     <p> 
      Modified By: 
      <%= Html.Encode(Model.Workstation.ModifiedBy) %> 
     </p> 
     <p> 
      Modified On: 
      <%= Html.Encode(String.Format("{0:g}", Model.Workstation.ModifiedOn)) %> 
     </p> 
     <p> 
      Created By: 
      <%= Html.Encode(Model.Workstation.CreatedBy) %> 
     </p> 
     <p> 
      Created On: 
      <%= Html.Encode(String.Format("{0:g}", Model.Workstation.CreatedOn)) %> 
     </p> 
    </fieldset> 
    <fieldset> 
     <legend>People</legend> 
     <% Html.RenderPartial("WorkstationPeople", Model.People); %> 
    </fieldset> 
    <fieldset> 
     <legend>Positions</legend> 
     <% Html.RenderPartial("WorkstationPositions", Model.Positions); %> 
    </fieldset> 
    <fieldset> 
     <legend>Items</legend> 

      <% using (Ajax.BeginForm("AddItem", "Home", null, 
        new AjaxOptions 
        { 
         UpdateTargetId = "ResultsGoHere", 
         InsertionMode = InsertionMode.Replace 
        }, 
        new { @id = "itemForm" })) 
      { %> 

       <label for="ItemID">Item:</label> 
       <%= Html.DropDownList("itemId", Model.ItemsList) %> 
       <%= Html.Hidden("workstationId", Model.Workstation.RecordID) %> 

       <a href="#" onclick="$('#itemForm').submit();">Submit</a> 

       <div id="ResultsGoHere"> 
        <% Html.RenderPartial("WorkstationItems", Model.Items); %> 
       </div> 

      <% } %> 
    </fieldset> 
    <br /> 
    <p> 
     <%=Html.ActionLink("Edit", "WorkstationEdit", new { id = Model.Workstation.RecordID }) %> 
     | 
     <%=Html.ActionLink("Back to List", "Index") %> 
    </p> 
</asp:Content> 

risposta

15

Che risultato si aspetta dal AJAX chiamare?

È possibile utilizzare i metodi di supporto dell'oggetto AjaxHelper anziché il numero HtmlHelper per il rendering del collegamento. Ad esempio, per ottenere nuovi contenuti con un'AJAX HttpPost chiamata e inserirlo in una <div> con l'impostazione ID per ResultsGoHere il rendering il seguente link:

<%= Ajax.ActionLink("Edit", "ItemEdit", 
         new { 
          itemId = item.RecordId, 
          workstationId = myWorkStationId 
         }, 
         new AjaxOptions { 
          HttpMethod="POST", 
          UpdateTargetId="ResultsGoHere", 
          InsertionMode = InsertionMode.Replace 
         }) %> 

Nella tua AcionMethod, si può semplicemente provare a Request.IsAjaxRequest() decidere cosa per tornare:

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult ItemEdit(string itemId, string workstationId) { 
    // edit the item and get it back 

    if (Request.IsAjaxRequest()) { 
     return PartialView("SingleItem", item); 
    } 
    return RedirectToAction("ItemEdit", new { itemId = item.RecordId, workstationId = workstationId }); 
} 

// fallback for get requests 
public ActionResult ItemEdit(string itemId, string workstationId) 
{ 
    // do stuff and return view 
} 
+0

Questo è fantastico! Ho ancora un problema, come posso passare due Id al controller? Devo passare in workstationId e itemId. Come estrarre l'elemento ID selezionato nel menu a discesa e utilizzarlo nel link di azione? – Lukasz

+0

È sufficiente aggiungere un parametro di input al metodo di azione e aggiungerlo ai valori del percorso. Se desideri ricevere un bel url per la chiamata, dovrai aggiungere un percorso corrispondente. Ho modificato il mio codice di conseguenza. –

+0

Un'ultima domanda, come posso ottenere il valore selezionato nell'elenco a discesa all'interno di Ajax.ActionLink? – Lukasz

2

Ecco come si potrebbe fare con il metodo Ajax.BeginForm() invece:

<% using (Ajax.BeginForm("ItemEdit", null, new AjaxOptions 
      { 
       UpdateTargetId = "ResultsGoHere", 
       InsertionMode = InsertionMode.Replace 
      }, new { @id = "itemForm" }) 
{ %> 
<p> 
    <%= Html.DropDownList("itemId") %></p> 
<p> 
    <%= Html.DropDownList("workstationId") %></p> 
<p> 
    <a href="#" onclick="$('#itemForm').submit();">Submit</a> 
</p> 
<% } %> 

Si prega di notare che il codice è nel suo stato attuale in alcun modo completamente funzionale - i dropdownlists non ottengono i loro articoli da nessuna parte, non c'è <div> per prendersi cura dei risultati dalla richiesta AJAX e l'attributo onclick sul il link che invia il modulo richiede che jQuery sia incluso (nel qual caso è meglio dare al link un id e aggiungere un gestore di eventi click() ad esso da un file js separato ...)

MODIFICA: Oh, e non ho verificato che sia corretto passare un valore null al parametro routeValues. In caso contrario, è sufficiente fornire i nomi dei controller e delle azioni e tutto andrà bene.

+0

Ho aggiunto altro codice alla fine della mia domanda. – Lukasz

+0

Che aspetto ha l'HTML reso? E il tuo ActionMethod? –

+0

L'HTML è solo il codice dalla vista parziale. Anche l'url era/Home/WorkstationDetail/1 e dopo il post è/Home/AddItem – Lukasz

0

come è possibile passare il modello dalla vista al post creare un'azione del controller utilizzando ajax.actionlink?

0

Qui, come di mia conoscenza, siamo in grado di passare i dati da Vista al controllore in due modi ...

  1. Utilizzando Formcollection costruito in parole chiave come questo ..

    [HttpPost] 
    public string filter(FormCollection fc) 
    { 
        return "welcome to filtering : "+fc[0]; 
            (or) 
        return "welcome to filtering : "+fc["here id of the control in view"]; 
    
    } 
    

FormCollection funzionerà solo quando si fa clic su qualsiasi pulsante all'interno di un modulo. In altri casi contiene solo i dati vuoti

  1. utilizzando classe del modello

    [HttpPost] 
    public string filter(classname cn) 
    { 
        return "welcome to filtering : "+cn.Empid+""+cn.Empname; 
    } 
    
0

in questo modo si sarà in grado di inviare più parametri attraverso ActionLink.
Per questa situazione si rimanda al codice qui sotto:

@Html.ActionLink("Link text", "Action Name", null, routeValues: new { pram_serviceLine = Model.ServiceLine_ID, pram_Month = Model.Month, pram_Year = Model.Year, flag = "ROTATION" } 

Rispondi se funziona.

Problemi correlati