my first question here.. :)
Let's begin with the code...
my page is
<form id="form1" runat="server">
<% using (Ajax.BeginForm(null)){%>
<%=Html.DropDownList("DdlScelta",MVC.Models.SelectLists.ConventionIdsSelectList, "Select by this list")%>
<%=Ajax.ActionLink("Show the Data", "SetData", new AjaxOptions { UpdateTargetId = "msg" })%>
<span id="msg"></span>
</form>
and this is my controller method
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SetData(FormCollection form1)
{
//form1["DdlScelta"] etc
}
I've also tried with a better way like
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SetData(string DdlScelta)
{
//not important code
}
but NOTHING to do, as soon one of the 2 actionResult is catched, I have a null value..
Thank you to any who can help me :)
You have to submit the form
<input type="submit" value="Somevalue" />
and have the form like this
Ajax.BeginForm("actionName", "controllerName", ajaxOptions)
Something like this
<% using (Ajax.BeginForm("actionName", "controllerName", ajaxOptions))
{%>
//form stuff
<input type="submit" value="Somevalue" />
<% } %>
Related
The issue i am facing has taken more then 8 hours but couldn't find the solution to it.
I am trying to implement ajax functionality in MVC4.
I've following code in index view.
#using (Ajax.BeginForm(
new AjaxOptions
{
HttpMethod = "get",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "resturantList"
}
))
{
<input type="search" name="searchTerm" />
<input type="submit" value="Search By Name" />
}
<div id="resturantList">
#foreach (var item in Model)
{
<div>
<h4>#item.Name</h4>
<div>#item.City, #item.Country</div>
<div>Reviews: #item.CountOfReviews</div>
<hr />
</div>
}
</div>
Following is html which renders when search button is clicked.
I've checked the script files references by firebug even they are included
<script src="/Scripts/jquery-2.1.0.js">
<script src="/Scripts/jquery-ui-1.10.4.js">
<script src="/Scripts/jquery.unobtrusive-ajax.js">
<script src="/Scripts/jquery.validate.js">
<script src="/Scripts/jquery.validate.unobtrusive.js">
Tried to remove the
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
from web.config file which solves the above stated issue but it also disables the client side validations.
You are not telling the form to post the data on which action of which controller, this is causing the problem,do like this, pass controller and action name as well:
#using (Ajax.BeginForm(
"Action", "Controller",
new AjaxOptions
{
HttpMethod = "get",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "resturantList"
}
))
{
<input type="search" name="searchTerm" />
<input type="submit" value="Search By Name" />
}
<div id="resturantList">
#foreach (var item in Model)
{
<div>
<h4>#item.Name</h4>
<div>#item.City, #item.Country</div>
<div>Reviews: #item.CountOfReviews</div>
<hr />
</div>
}
</div>
and second thing,make sure you are returning a partial view,if full view is returing that will also cause issues.Do this in you view for it:
#{
Layout = null
}
Actually you have to return partial view in the response of ajax call
I have built a 'buy products' page dynamically by building it up for each product. Each product has an 'Add to Basket' button, which are differentiated for each product by having the pID as the buttons name attribute. I now want to get the value of the name attribute within my controller on postback. Not sure how to do this:
View:
#foreach (Ecommerce.Models.HomeModels.Product product in Model)
{
using (Html.BeginForm())
{
#Html.Label(product.Name);
<br />
#Html.Label(product.Description);
<br />
#Html.Label(product.UnitPrice.ToString());
<p></p>
<input name="#product.ID" type="submit" value="Add to Basket" />
}
}
Controller:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult BuyProducts(string button)
{
}
If you don't have multiple submit buttons inside a form then there is no need to know on the server side what was the name of the clicked submit button. There are other ways to send back your Id to the server:
Why don't you just generate a hidden field inside your form to hold and post the data?
#foreach (Ecommerce.Models.HomeModels.Product product in Model)
{
using (Html.BeginForm())
{
<input type="hidden" name="productId" value="#product.ID" />
<input type="submit" value="Add to Basket" />
}
}
Then you can get the value of the hidden field in your controller:
public ActionResult BuyProducts(string productId)
{
//..
}
OK, I'm sorry if the tile of the question was unclear, and if you understand what I mean, please don't hesitate to help me think of a better one.
Anyway, I have a <input type="submit"> element for my form, and I want it to return the same URL as the URL of the page the element is on.
Currently, if I click the button, it takes me from /Calculate/Quadratic to /Calculate/QuadraticForm
In my controller for this view, I have the following code:
[AcceptVerbs(HttpVerbs.Get)]
public ViewResult Quadratic()
{
ViewData["Root1"] = "";
ViewData["Root2"] = "";
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public ViewResult Quadratic(QuadCalc boss)
{
ViewData["Root1"] = x1;
ViewData["Root2"] = x2;
return View();
}
And here is the markup and code for my Quadratic view page, which includes the form which includes the submit button I've been referring to:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Quadratic</h2>
<% using(Html.BeginForm("QuadraticForm", "Calculate")) %>
<% { %>
<div>
a: <%= Html.TextBox("quadraticAValue") %>
<br />
b: <%= Html.TextBox("quadraticBValue") %>
<br />
c: <%= Html.TextBox("quadraticCValue") %>
<br />
<input type="submit" id="quadraticSubmitButton" value="Calculate!" />
<br />
<p><%= ViewData["Root1"] %></p>
<p><%= ViewData["Root2"] %></p>
</div>
<% } %>
</asp:Content>
Therefore, all I really want is to have the submit button return the same page, but the HTTP post will aid the application in passing new ViewData. Unless I'm interpreting this all wrong.
The problem is in your BeginForm method that calls the QuadraticForm action
<% using(Html.BeginForm("QuadraticForm", "Calculate")) %>
If you want to give an ID to the form you should use
<% using (Html.BeginForm("Quadratic", "Calculate", FormMethod.Post, new { id = "QuadraticForm" })) { %>
If you dont mind about the ID and want to just return to the same action just use
<% using(Html.BeginForm() %>
The parameters are:
The action name
The controller Name
The form method (get/post)
The form attributes
Given the following view model and action using the DefaultModelBinder, it seems to ignore the dictionary, but bind all other properties correctly. Am I missing something here? Looking at the MVC source code this seems legit.
Thanks
public class SomeViewModel
{
public SomeViewModel()
{
SomeDictionary = new Dictionary<string, object>();
}
public string SomeString { get; set; }
public IDictionary<string, object> SomeDictionary { get; set; }
}
[HttpPost]
public ActionResult MyAction(SomeViewModel someViewModel)
{
//someViewModel.SomeString binds correctly
//someViewModel.SomeDictionary is null
}
<%# Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage<SomeViewModel>" MasterPageFile="~/Views/Shared/Site.Master" %>
<asp:Content runat="server" ID="Content2" ContentPlaceHolderID="MainContent">
<% using (Html.BeginForm("MyAction", "MyController")) {%>
<%= Html.EditorFor(m => m.SomeString) %>
<%= Html.EditorFor(m => m.SomeDictionary["somevalue"]) %>
<input type="submit" value="Go" />
<%} %>
</asp:Content>
And for reference, the HTML output is:
<input class="text-box single-line" id="SomeString" name="SomeString" type="text" value="" />
<input class="text-box single-line" id="Somedictionary_somevalue_" name="SomeDictionary[somevalue]" type="text" value="" />
EDIT: The above will not work as pointed out below, however I prefer this layout and the following quick hack works for my needs, call this just after posting...
someViewModel.SomeDictionary = (from object key in Request.Form.Keys
where key.ToString().StartsWith("SomeDictionary[")
select new
{
Key = key.ToString().Replace("SomeDictionary[", string.Empty).Replace("]", string.Empty),
Value = (object)Request.Form[key.ToString()]
}).ToDictionary(arg => arg.Key, arg1 => arg1.Value);
It needs some tidying up ofcourse :)
You may take a look at this post to see how dictionaries should be binded. I am afraid that using strongly typed EditorFor helpers you won't be able to achieve this and you will have to generate the fields manually.
I am currently using the EntityFramework to bind my ASP.NET MVC project to a MySQL database and one of my entities, Product, has an Images property containing a collection of ProductImages. I have built a form to allow the user to modify a given Product and this form includes fields for editing all of the images associated to that Product as well. After reading Phil Haack's and Dan Miser's posts on the matter I have a decent idea of what needs to happen, but I can't seem to make it work for some reason...
Here is my Product form:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<KryptonCMS.Models.Product>" %>
<%# Import Namespace="KryptonCMS.Core" %>
<%# Import Namespace="KryptonCMS.Models.ViewModels" %>
<% using (Html.BeginForm())
{%>
<ul class="gallery">
<%
var index = 0;
foreach (var image in Model.ImageList.OrderBy(p => p.Order))
{
%>
<li>
<% Html.RenderPartial("ProductImageForm", image, new ViewDataDictionary(ViewData) { { "index", index } }); %>
</li>
<%
index++;
}
%>
</ul>
<p>
<input type="submit" name="btnSave" value="Save" />
<input type="submit" name="btnCancel" value="Cancel" />
</p>
<% } %>
And here is the definition for ProductImageForm:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<KryptonCMS.Models.ProductImage>" %>
<%# Import Namespace="KryptonCMS.Core" %>
<div>
<%
var fieldPrefix = string.Format("images[{0}]", ViewData["index"]); %>
<%=Html.Hidden(fieldPrefix + "ID", Model.ID) %>
<img src="<%=UtilityManager.GetProductImagePath(Model.Product.ID, Model.FileName, true) %>"
alt="" /><br />
<label for="Description">
Description:</label>
<%=Html.TextBox(fieldPrefix + "Description", Model.Description) %><br />
<label for="Order">
Order:</label>
<%=Html.TextBox(fieldPrefix + "Order", Model.Order)%><br />
</div>
And finally my ProductsController actions:
public ActionResult Edit(int id)
{
var product = productsRepository.GetProduct(id);
if (product == null)
return View("NotFound", new MasterViewModel());
// else
return View(ContentViewModel.Create(product));
}
[AcceptVerbs(HttpVerbs.Post), ValidateInput(false)]
public ActionResult Edit(int id, FormCollection formCollection)
{
var product = productsRepository.GetProduct(id);
if (formCollection["btnSave"] != null)
{
if (TryUpdateModel(product) && TryUpdateModel(product.Images, "images"))
{
productsRepository.Save();
return RedirectToAction("Details", new { id = product.ID });
}
return View(ContentViewModel.Create(product));
}
// else
return RedirectToAction("Details", new { id = product.ID });
}
The HTML output for a single ProductImageForm looks like this:
<div>
<input id="images[0]ID" name="images[0]ID" type="hidden" value="1" />
<img src="/Content/ProductGallery/3/thumbs/car1.jpg"
alt="" /><br />
<label for="Description">
Description:</label>
<input id="images[0]Description" name="images[0]Description" type="text" value="FAST CAR" /><br />
<label for="Order">
Order:</label>
<input id="images[0]Order" name="images[0]Order" type="text" value="1" /><br />
</div>
I have tried all sorts of methods of reorganizing my form including taking the Image collection out of the Product form and placing it in its own (which I really don't want to do), but nothing is working. Is there something blatatently wrong with my approach here?
You are missing dots in inputs' names:
<%= Html.Hidden(fieldPrefix + ".ID", Model.ID) %>
<%= Html.TextBox(fieldPrefix + ".Description", Model.Description) %>
<%= Html.TextBox(fieldPrefix + ".Order", Model.Order) %>
Check this blog post: http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx