2009-06-18 166 views
12

Tengo una vista con una cuadrícula que contiene elementos agregados a una estación de trabajo. El usuario puede seleccionar un elemento de una lista desplegable y hacer clic en un enlace de acción que llama a un controlador que agrega ese elemento a la estación de trabajo. Puedo hacerlo funcionar leyendo el objeto FormCollection en la acción de publicación del controlador.ASP.NET MVC Pasar datos de la vista al controlador

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

Lo que quiero hacer es ser capaz de presentar los dos parámetros de la workstationId y ITEMID al controlador usando Ajax.ActionLink y tienen el nuevo elemento que se ha añadido quedar insertado en la red . Estoy haciendo que la red de la siguiente manera:

<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> 

El problema que tengo es cuando envío utilizando el ActionLink no puedo encontrar la manera de pasar de los parámetros para el controlador y la forma de actualizar la red sin tener que recargar la toda la vista

Realmente agradecería algo de ayuda con esto o incluso un enlace a un tutorial que hace algo similar.

¡Gracias!

Esta es la versión de trabajo, el único problema es que cuando el controlador devuelve la vista parcial que es todo lo que se obtiene, la página real se va.

<% 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> 

<% } %> 

No estoy seguro de cuál es la causa, el reemplazo funcionaba correctamente antes pero el controlador no obtenía el valor desplegable. Ahora el controlador está obteniendo el valor, pero la vista parcial que se devuelve reemplaza a toda la página.

el método de acción:

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

Este es el código HTML de la opinión de que hace todo el trabajo:

<%@ 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> 

Respuesta

15

Qué resultado esperas de la AJAX llamar?

Puede utilizar los métodos de ayuda del objeto AjaxHelper en lugar del HtmlHelper para representar el enlace. Por ejemplo, para conseguir nuevos contenidos con un HttpPost llamada AJAX e insertarla en un <div> con el ID de unidad para ResultsGoHere renderizar el siguiente enlace:

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

En su AcionMethod, sólo tiene que probar en Request.IsAjaxRequest() para decidir qué para volver:

[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

Esto es genial! Todavía tengo un problema, ¿cómo paso dos Id's al controlador? Necesito pasar en workstationId y itemId. ¿Cómo extraigo el itemId que se seleccionó en el menú desplegable y lo uso en Action Link? – Lukasz

+0

Puede simplemente agregar un parámetro de entrada al método action y agregarlo a los valores de la ruta. Si desea obtener una buena URL para la llamada, deberá agregar una ruta correspondiente. He editado mi código en consecuencia. –

+0

Una última pregunta, ¿cómo obtengo el valor seleccionado de la lista desplegable dentro de Ajax.ActionLink? – Lukasz

2

Ésta es la forma en que podría hacerlo utilizando el método Ajax.BeginForm() lugar:

<% 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> 
<% } %> 

Tenga en cuenta que el código está en su estado actual de ninguna manera completamente funcional - las listas desplegables no obtienen sus elementos desde ningún lugar, no hay <div> para atender los resultados de la solicitud AJAX, y el atributo onclick en el El enlace que envía el formulario requiere que se incluya jQuery (en cuyo caso es mucho mejor darle un identificador al enlace y agregarle un controlador de eventos click() desde un archivo separado js ...)

EDITAR: Ah, y no he verificado que esté bien pasar un valor null al parámetro . Si no, solo proporcione los nombres de controlador y acción, y estará bien.

+0

He agregado más código al final de mi pregunta. – Lukasz

+0

¿Cómo se ve el HTML renderizado? ¿Y tu ActionMethod? –

+0

El HTML es solo el código de vista parcial. También la url era/Home/WorkstationDetail/1 y después de la publicación es/Home/AddItem – Lukasz

0

¿cómo se puede pasar el modelo de la vista a la acción de creación de la publicación del controlador utilizando ajax.actionlink?

0

Aquí, como de mi conocimiento, podemos pasar los datos al controlador de vista de dos maneras ...

  1. Usando Formcollection construido en palabras clave como éste ..

    [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 funcionará solo cuando haga clic en cualquier botón dentro de un formulario. En otros casos, sólo contiene los datos vacíos

  1. usando clase de modelo

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

Esto es cómo va a ser capaz de enviar varios parámetros a través ActionLink.
Para esta situación se refieren a favor el código de abajo:

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

Responder si funciona.

Cuestiones relacionadas