ASP page not receiving POST parameters - post

I am writing a small application in Classic ASP. I have a page which has a form, which posts to a second page. Included with the form's POST, are file uploads, hence the need for a POST method.
The second page though is NOT seeing ANY of the fields being sent by the first page. Calling either Request("param") or Request.Form("param") both just return empty string.
If i switch the method on my form from POST to GET (with NO other changes), then the values are properly picked up by the receiving page, of course then I cannot do the file uploads, which are a crucial part of this application.
In GET mode, the parameters are all put on the url as expected. In POST mode, I fired up FireBug, and examined the POST data of my request. The originating form IS sending all the values in the request (they show up in FireBug as expected), so the problem seems to be on the receiving page's end.
The form is being submitted via code, called from the button with the onclick="javascript:saveMinutes();"
My form and the saveMinutes() function are declared as follows:
<form id="frmMinutes" enctype="multipart/form-data" method="post" action="saveminutes.asp">
<table id="tblMinutes" style="width: 100%;">
<tr>
<td>
<select id="selYear" name="year" size="13" onclick="javascript:setDatePickerRange(); checkForMinutes();">
<%For lc = Year(Now) To getMinutesFirstYear() Step - 1%>
<option value="<%=lc%>" <%If lc = Year(Now) Then%>selected="selected"<%End If%>><%=lc%></option>
<%Next%>
</select>
</td>
<td>
<select id="selMonth" name="month" size="13" onclick="javascript:setDatePickerRange(); checkForMinutes();">
<%For lc = 1 To 12%>
<option value="<%=lc%>" <%If lc = Month(Now) Then%>selected="selected"<%End If%>"><%=MonthName(lc)%></option>
<%Next%>
</select>
</td>
<td style="width: 100%; padding-left: 20px;">
<table id="enterMinutes" style="width: 100%">
<tr>
<th>Topic:</th>
<td><input id="topic" name="topic" type="text" maxlength="100" field="topic" /></td>
</tr>
<tr>
<th>Presenter:</th>
<td><input id="presenter" name="presenter" type="text" maxlength="100" field="presenter" /></td>
</tr>
<tr>
<th>Date:</th>
<td><input id="mtgdate" name="mtgdate" type="text" maxlength="10" class="datepick" field="mtgdate" readonly="readonly" /></td>
</tr>
<tr>
<th style="vertical-align: top;">Files:</th>
<td style="text-align: left;">
<input id="file0" name="file0" type="file" size="35" /><span class="redEmphasis" style="margin: 0px 10px 0px 10px;">(.doc or .docx)</span><input type="button" value="+" onclick="javascript:addFileUpload();" />
</td>
</tr>
<tr>
<th style="vertical-align: top;"></th>
<td style="text-align: left; padding: 10px 0px 10px 0px;">
<input type="button" style="width: 100%" value="update minutes" onclick="javascript:saveMinutes();" />
</td>
</tr>
</table>
<span id="warnexist" class="redEmphasis" style="display: none;">The selected month already has associated minutes (). doc files take precedence over docx.</span>
</td>
</tr>
</table>
</form>
saveMinutes():
function saveMinutes() {
if($('form#frmMinutes input[type=text]').filter(function () { return $(this).val() == '' }).length > 0) {
alert('Please enter all fields.');
return;
}
if ($('form#frmMinutes input#file0').filter(function () { return !$(this).val().match(/.*\.docx?$/i) }).length > 0) {
alert('First file must be doc or docx.');
return;
}
$('form#frmMinutes input[type=file]').filter(function () { return $(this).val() == '' }).next().remove();
$('form#frmMinutes input[type=file]').filter(function () { return $(this).val() == '' }).remove();
removeDupeFiles();
// reindex file inputs after removing emptys/dupes
var fs = $('form#frmMinutes input[type=file]:gt(0)');
for (lc = 1; lc <= fs.length; lc++) {
var fid = 'file' + new String(lc);
$(fs[lc-1]).attr('id', fid).attr('name', fid);
}
$('form#frmMinutes')[0].submit();
}

When your from is encoded as multipart, you can't get the POST values as plain old parameters. They are just additional parts of the multipart form.
To retrieve the uploaded files in ASP, you typically have to loop through the parts and check each one to see if it is a file (and then save it if it is). To get field values, you have to add to that loop to check each part to see if it has the name of one of your field values, and then retrieve the value. This is a pain to do in pure ASP code, so many people use some type of file upload component, in which case the retrieval of field values will depend on the component.
But the basic message is: whatever parsing of the form you're doing to retrieve the files, you have to do the same thing to retrieve the field values.

Related

MVC- drop down values not binding for all the rows in a table

The model:
public class EdituserModel : IEnumerable<EdituserModel>
{
public int UserID { get; set; }
public string Status { get; set; }
public IEnumerator<EdituserModel> GetEnumerator()
{
return ((IEnumerable<EdituserModel>)editUser).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<EdituserModel>)editUser).GetEnumerator();
}
}
The View:
<table id="tbltbl_usertable" class="tableasd" cellpadding="0" cellspacing="0">
<tr>
<th style="width:115px;text-align: center; ">User Id</th>
<th style="width:100px;text-align: center;">Status</th>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
#foreach (var user in Model)
{
<tr>
<td class="UserID" style="text-align: center; ">
<span style="text-align: center;">#user.UserID</span>
</td>
<td class="Status" style="text-align: center;">
<select id="SelectedStatusId" name="SelectedStatusId" value="#user.Status" >
<option value="A" selected="selected">Admin</option>
<option value="U">Dashboard user</option>
</select>
</td>
</tr>
}
</table>
From the above code, the UserID is being displayed properly (8 rows for 8 users). But only one drop down is being displayed for the first row and not the subsequent rows. Is there something I'm missing?
The way you're binding to the select is wrong. You can't set an option in the dropdown by setting the value attribute of select (try it). Besides, you're setting selected="selected" on the first option. I'm guessing that is selected in all the dropdowns.
"Only one drop down is being displayed for the first row and not the subsequent rows":
I don't know how this is possible. I have tested this in my system and it wasn't reproducible.
So, how to bind your value to the dropdown? You should use MVC's DropdownListFor HTML Helper.
#for (var i = 0; i < Model.Count(); i++)
{
<tr>
<td class="UserID" style="text-align: center; ">
<span style="text-align: center;">Model.editUser[i].UserID</span>
</td>
<td class="Status" style="text-align: center;">
#Html.DropDownListFor(m => Model.editUser[i].Status, new SelectList(new[] {
new { Text = "Admin", Value = "A" },
new { Text = "Dashboard user", Value = "U" },
}, "Value", "Text", Model.editUser[i].Status))
</td>
</tr>
}
You should use a for loop instead of foreach whenever you're looping and creating form elements in MVC (Why though?). This generates appropriate name attribute which are important when submitting forms.
(We usually get the SelectListItems in a ViewBag and bind. But there is an issue in MVC with DropDownList helper when we are looping)
"BUT I DONT CARE ABOUT GIVING PROPER NAMES TO FORM ELEMENTS
OR DROPDOWNLISTFOR OR ANY OF THAT STUFF. I JUST WANT TO BIND MY DROPDOWN OKAY?":
Then:
#for (var i = 0; i < Model.Count(); i++)
{
<tr>
<td class="UserID" style="text-align: center; ">
<span style="text-align: center;">#Model.editUser[i].UserID</span>
</td>
<td class="Status" style="text-align: center;">
<select id="SelectedStatusId" name="SelectedStatusId">
<option value="A" #(Model.editUser[i].Status == "A" ? "selected" : "" )>Admin</option>
<option value="U" #(Model.editUser[i].Status =="U" ? "selected" : "" )>Dashboard user</option>
</select>
</td>
</tr>
}
UPDATE: I saw your update now reagarding the Enumerator. See, this is why I asked you post all the relevant code. You said your model for the page was IEnumerable<EdituserModel>. My asnwer would still work. Replace all the Model[i] with Model.editUser[i] (otherwise you'd have implement IList as well)

POST action returns the model in a valid state but returns Model.Count as 0 when using foreach or for loop

As shown in my post here the GET action method Test(..) works fine when using foreach loop in the corresponding Test.chtml view but the POST action method Test(...) returns null. But, as mentioned by many users, the foreach is not reliable for POST method. So, I decided to use the for loop as shown below. But that returned unexpected results in the view since, according to this post, in a foreachloop type casting is done automatically but in for loop you have to type cast the objects Model[i].BlogID etc to a proper class object type.
So, I decided to type cast the objects Model[i].BlogID etc to a BlogsWithRelatedPostsViewModel class object type as shown in the second version of Test.cshml view below; and this time the Test.cshtml view is displayng the correct records. But although the submit button in the view is sending a a valid model (ModelState.IsValid is true) the Model.Count is 0 that results in no update to database. Why Model.Count is 0 and how to correct it? As you can see below the html page source of the view is showing the name attributes of the tags matching the property values in the View Model.
Note: For complete code, please see this OP. I'm using ASP.NET Core with EF Core and Tag Helpers.
Test.cshtml view with for loop - without type casting the loop objects:
#model IList<ASP_Core_Blogs.Models.BlogPostViewModels.BlogsWithRelatedPostsViewModel>
#using ASP_Core_Blogs.Models.BlogPostViewModels
#{ ViewData["Title"] = "Index"; }
<div class="row">
<div class="col-md-12">
<form asp-controller="Blogs" asp-action="Test" asp-route-returnurl="#ViewData["ReturnUrl"]" method="post">
#{
IEnumerable<SelectListItem> yearsList = (IEnumerable<SelectListItem>)ViewBag.YearsList;
var currentlySelectedIndex = 0; // Currently selected index (usually will come from model)
}
<strong>Select a Post Year</strong>
<h6>Choose a year and a URL to begin:</h6>
<label>Year:</label><select asp-for="#currentlySelectedIndex" asp-items="yearsList"></select><input type="submit" class="btn btn-default" name="GO" value="GO" />
<table class="table">
<thead>
<tr>
<th></th>
<th></th>
<th>Url</th>
<th>Title</th>
<th>Content</th>
</tr>
</thead>
<tbody>
#for (int i=0; i< Model.Count(); i++)
{
<tr>
<td><input type="hidden" asp-for="#Model[i].BlogID" /></td>
<td><input type="hidden" asp-for="#Model[i]).PostID" /></td>
<td>
<input type="text" asp-for="#Model[i].Url" style="border:0;" readonly />
</td>
<td>
<input asp-for="#Model[i].Title" />
</td>
<td>
<input asp-for="#Model[i].Content" />
</td>
</tr>
}
</tbody>
</table>
<button type="submit" class="btn btn-default">Save</button>
</form>
</div>
</div>
Test.cshtml view with for loop objects being casted as BlogsWithRelatedPostsViewModel class objects:
#model IList<ASP_Core_Blogs.Models.BlogPostViewModels.BlogsWithRelatedPostsViewModel>
#using ASP_Core_Blogs.Models.BlogPostViewModels
#{ ViewData["Title"] = "Index"; }
<div class="row">
<div class="col-md-12">
<form asp-controller="Blogs" asp-action="Test" asp-route-returnurl="#ViewData["ReturnUrl"]" method="post">
#{
IEnumerable<SelectListItem> yearsList = (IEnumerable<SelectListItem>)ViewBag.YearsList;
var currentlySelectedIndex = 0; // Currently selected index (usually will come from model)
}
<strong>Select a Post Year</strong>
<h6>Choose a year and a URL to begin:</h6>
<label>Year:</label><select asp-for="#currentlySelectedIndex" asp-items="yearsList"></select><input type="submit" class="btn btn-default" name="GO" value="GO" />
<table class="table">
<thead>
<tr>
<th></th>
<th></th>
<th>Url</th>
<th>Title</th>
<th>Content</th>
</tr>
</thead>
<tbody>
#for (int i=0; i< Model.Count(); i++)
{
<tr>
<td><input type="hidden" asp-for="((BlogsWithRelatedPostsViewModel)#Model[i]).BlogID" /></td>
<td><input type="hidden" asp-for="((BlogsWithRelatedPostsViewModel)#Model[i]).PostID" /></td>
<td>
<input type="text" asp-for="((BlogsWithRelatedPostsViewModel)#Model[i]).Url" style="border:0;" readonly />
</td>
<td>
<input asp-for="((BlogsWithRelatedPostsViewModel)#Model[i]).Title" />
</td>
<td>
<input asp-for="((BlogsWithRelatedPostsViewModel)#Model[i]).Content" />
</td>
</tr>
}
</tbody>
</table>
<button type="submit" class="btn btn-default">Save</button>
</form>
</div>
</div>
A Portion of html generated by View after Submit:
<tr>
<td><input type="hidden" data-val="true" data-val-required="The BlogID field is required." id="BlogID" name="BlogID" value="1" /></td>
<td><input type="hidden" data-val="true" data-val-required="The PostID field is required." id="PostID" name="PostID" value="1" /></td>
<td>
<input type="text" style="border:0;" readonly id="Url" name="Url" value="blog1#test.com" />
</td>
<td>
<input type="text" id="Title" name="Title" value="Title1" />
</td>
<td>
<input type="text" id="Content" name="Content" value="Content1" />
</td>
</tr>

How to send Id to Controller from Ajax Input Button

I have this grid which has an edit button. How do I add code to the input button so that the value of the Id is sent to the Controller?
#using (Ajax.BeginForm("EditLineItem", "OrderSummary", new AjaxOptions() { InsertionMode = InsertionMode.Replace, UpdateTargetId = "content" })) {
<div id="summaryGrid">
<table >
<tr>
<th>Report Type</th>
<th>Borrower Name</th>
<th>Property Address</th>
<th>Est Comp Date</th>
<th>Report Price</th>
<th>Exp Fee</th>
<th>Disc.</th>
<th>Total Price</th>
</tr>
#{
foreach (var item in Model) {
<tr>
<td >#item.ReportName</td>
<td >#item.BorrowerName</td>
<td >#item.Address</td>
<td >#item.EstimatedCompletionDate</td>
<td >#item.ReportPrice</td>
<td >#item.ExpediteFee</td>
<td >#item.Discount</td>
<td >#item.TotalPrice</td>
<td >#item.Id</td>
<td ><input type="submit" value="Edit" /></td>
</tr>
}
}
</table>
</div>
}
just put a name on your input button.
<input type="submit" name="id" value="edit" />
Then on your action, you should be able to get the value for id.
If you want more complexity then you are going to have to rethink the way you are doing it. Most likely by writing your own JQuery methods.
$('input.edit').on('click', function (evt) {
evt.preventDefault();
var values = $(this).data();
$.post($(this).attr('href'), values, function (result) { /*do something*/ });
});
Html :
<a href="/edit/1" class="edit" type="submit" data-id="1" data-method="edit" />
That's a start, but you could probably tweak it to fit your needs. At that point, you don't need to wrap the whole table with the Ajax.BeginForm.
To add to Khalid's answer: I tested with this form:
<form method="get">
<input type="submit" name="Id1" value="Edit" id="id1" />
<input type="submit" name="Id2" value="Edit" id="id2" />
<input type="submit" name="Id3" value="Edit" id="id3" />
</form>
The post looks like this when clicking on the third button:
http://localhost:34605/HtmlPage.html?Id3=Edit
In other words, the browser passes the name of whichever button is clicked.
This is an example of getting the Id in the controller:
if (Request.QueryString.HasKeys()) {
string key = Request.QueryString.GetKey(0);
int id;
int.TryParse(key.Substring(2, 1), out id);
Response.Write("You selected id: " + id);
}
I have since found an even easier way of doing this:
Use the <button> element instead of <input>
With <button> you can do this:
<button type="submit" value="#item.Id" name="id">Edit</button>
and then in the controller, all you need is this:
public ActionResult EditLineItem(int id)
{ //Do something with id}
Note that this does not work with IE6.

create div dynamically on click of a hyperlink in asp.net mvc

1.I want to dynamically generate div containing textbox with unique id on click of button
<input id="<%:rid %>" type="button" value="reply"/>
2.I also want to use jquery ajax mathod to carry the textbox data to ashx file .
Can anyone help me
code
var lineItemCount = 0;
$(document).ready(function () {
$(".commentbox input[type='button']").click(function () {
var id = $(this).attr("id");
alert(id);
var cid = id.substring(5);
var containerid = "container" + cid;
alert(containerid);
//Increase the lineitemcount
lineItemCount++;
//Add a new lineitem to the container, pass the lineItemCount to makesure
getLineItem()
// can generate a unique lineItem with unique Textbox ids
$(containerid).append(getLineItem(lineItemCount));
});
});
//Create a new DIV with Textboxes
function getLineItem(number) {
var div = document.createElement('div');
//Give the div a unique id
div.setAttribute('id', 'lineitem_' + number);
//pass unique values to the getTextbox() function
var t1 = getTextbox('txt_' + number + '_1');
div.appendChild(t1);
return div;
}
//Create a textbox, make sure the id passed to this function is unique...
function getTextbox(id) {
var textbox = document.createElement('input');
textbox.setAttribute('id', id);
textbox.setAttribute('name', id);
return textbox;
}
iteration through model in aspx page
<%var i=1;%>
<%foreach (var commentitem in item.commentsModelList)
{
<table border="0" class="commentbox">
<tr>
<%var rid = "reply" + i;%>
<div id="<%:containerid %>">
<td> <input id="<%:rid %>" type="button" value="reply"/>
</div>
</td>
</tr>
</table>
<% i++;}%>
I changed your markup little bit to get the corresponding id of items on my click events
HTML
<table border="0" class="commentbox">
<tr>
<td>Some Item text
</td>
</tr>
<tr>
<td>
<div id="container-1" ></div>
<input type="button" class='btnReply' id="reply-1" value="Reply" />
</td>
</tr>
</table>
And the Script
$(function(){
$(".commentbox .btnReply").click(function(){
$(this).hide();
var id=$(this).attr("id").split("-")[1]
var strDiv="<input type='text' class='txtCmnt' id='txtReply-"+id+"' /> <input type='button' class='btnSave' value='Save' id='btnSave-"+id+"' /> ";
$("#container-"+id).html(strDiv);
});
$(".commentbox").on("click",".btnSave",function(){
var itemId=$(this).attr("id").split("-")[1]
var txt=$(this).parent().find(".txtCmnt").val();
$.post("/echo/json/", {reply: txt, id: itemId},function(data){
alert(data);
//do whatever with the response
})
});
});
Here is the jsfiddle example : http://jsfiddle.net/UGMkq/30/
You need to change the post target url to your relevant page which handles the ajax response.
EDIT : As per the comment about handing Multiple Divs
As long as you have the container div ids unique, it will work, I just changed the markup to include more than one item.
<table border="0" class="commentbox">
<tr>
<td>Some Item text<br/>
<div id="container-1" ></div>
<input type="button" class='btnReply' id="reply-1" value="Reply" />
</td>
</tr>
<tr>
<td>Some Another Content here <br/>
<div id="container-2" ></div>
<input type="button" class='btnReply' id="reply-2" value="Reply" />
</td>
</tr>
</table>
Here is the sample :http://jsfiddle.net/UGMkq/44/
For the above output to be rendered, you probably want to write your razor syntax like this
<table border="0" class="commentbox">
#foreach (var commentitem in item.commentsModelList)
{
<tr>
<td>Some Another Content here<br/>
<div id="container-#(commentitem.Id)" ></div>
<input type="button" class='btnReply' id="reply-#(commentitem.Id)" value="Reply" />
</td>
</tr>
}
</table>
Instead of creating a new table for each item, I created a new row in existing table.

Getting Posted Data from a Dynamic Form with MVC

I have a page that contains a form, where part of it is dynamically generated based off of what SKU's are on an order.
<% for each i in ViewData.Model %>
<script type="text/javascript">
$(function () {
$('#return_<%=i.SKUN%>').change(function () {
if ($('#return_<%=i.SKUN%>').val() > $('#qty_<%=i.SKUN%>').val()) {
$('#Discrepancy').val("Yes");
} else {
$('#Discrepancy').val("");
}
});
});
</script>
<tr>
<td style="text-align: left"><%= i.SKUN%></td>
<td style="text-align: left; width: 360px"><%= i.DESCR%></td>
<td style="text-align: left">£<%= i.PRIC%></td>
<td style="text-align: left"><%= i.QUAN%></td>
<td style="text-align: left">£<%= i.EXTP%></td>
<td style="text-align: left"><input type="hidden" name="qty_<%=i.SKUN%>" id="qty_<%=i.SKUN%>" value="<%= i.QUAN%>"/><input type="text" name="return_<%=i.SKUN%>" id="return_<%=i.SKUN%>" style="width:50px;" class="required"/>
<% If i.FLAG3 = "T" Then
%> <img src="../../Content/images/icons/error.png" alt="This SKU is subject to a <%=Html.ViewData("RestockFee") %>% restocking fee" title="This SKU is subject to a <%=Html.ViewData("RestockFee") %>% restocking fee"/><%
End If%>
</td>
</tr>
<% Next%>
It's by no means perfect, but it gets the job done at the moment.
The part I'm struggling with is as return_<%=i.SKUN%> is a series of dynamically generated text boxes that change for each order, though they remain with the naming convention of return_<%=i.SKUN%>, how do I get the values for them in my controller that handles the form post?
EDIT: It's also important to note that none of these fields are required fields and that the number of text boxes varies per order.
Can't you change the naming convention to:
<input
type="text"
name="skuns[<%= index %>]"
id="return_<%= i.SKUN %>"
style="width:50px;"
class="required"
value="<%= i.SKUN %>"
/>
where index would be an incrementing variable from 0 to n. This way your controller action could look like this:
Public Function Result(skuns As String()) As ActionResult
And leave the default model binder do the job.

Resources