I have a MasterPage, in my Views\Shared folder. I have an index.aspx in my Views\Home folder. And I have a login.ascx (user control) in my Views\User folder. The ascx file is added to my MasterPage:
<% Html.RenderPartial(#"~\Views\User\login.ascx");%>
The code in the ascx is pointing the submit form to a UserController.cs in my Controllers folder.
Here's the ascx:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<BudgieMoneySite.Models.SiteUserLoginModel>" %>
<% using (Html.BeginForm("UserLogin", "User"))
{%>
<table width="300">
<tr>
<td colspan="3" align="center">
User Login
</td>
</tr>
<tr>
<td align="right">
<%=Html.LabelFor(m => m.Username)%>
</td>
<td>
<%=Html.TextBoxFor(m => m.Username)%>
</td>
<td>
</td>
</tr>
<tr>
<td align="right">
<%=Html.LabelFor(m => m.Password)%>
</td>
<td>
<%=Html.PasswordFor(m => m.Password)%>
</td>
<td>
</td>
</tr>
<tr>
<td>
</td>
<td>
<%=Html.CheckBoxFor(m => m.RemeberMe)%><%=Html.LabelFor(m => m.RemeberMe)%>
</td>
</tr>
<tr>
<td colspan="2">
</td>
<td colspan="3" align="right">
<input id="Submit1" type="submit" runat="server" value="Login" />
</td>
</tr>
</table>
<%
} // End Using.%>
If I ctrl+click the Controller name and the method, in the Html.BeginForm area, it takes me to my method that should be called when I click Sybmit.
The method that this should call, in my UserController, has this code defined:
[HttpPost]
public ActionResult UserLogin(SiteUserLoginModel model)
{
try
{
if (MembershipService.ValidateUser(model.Username, model.Password))
{
FormService.SignIn(model.Username, model.RemeberMe);
PersonDto user = SiteUserLoginModel.LoadLoggedInUserDetails(model.Username);
Session.Add("current_firstname", user.Firstname);
Session.Add("current_userid", user.PersonId);
}
return RedirectToAction("Index", "Home");
}
catch (ArgumentException e)
{
ViewData["ErrorMessage"] = e.Message;
return RedirectToAction("Index", "Home");
}
}
However, when I click the submit button at runtime, this method is never called. The screen just refreshed. The HomeController does fire though, as the index screen is refreshed, I think. But the breakpoint in my method above never fires.
What am I doing wrong?
I would start removing the runat="server" attribute from your submit button...
<input id="Submit1" type="submit" value="Login" />
Your form in BeginForm isn't set to POST.
Try this: Html.BeginForm("UserLogin", "User", FormMethod.Post).
Guys, I found the issue, and it's an issue I had 2 weeks back, but totoally forgot. The master page had a Form tag! And the user control's Form tage was being hidden by the master page's one. I remove the Form tags from the master page, and it's resolved.
Related
I have the following table:
<form method="post" asp-action="Index" asp-controller="Record">
<table class="table table-hover">
<thead>
<tr>
<th scope="col"><input type="checkbox" id="chkAll"></th>
<th scope="col">Created</th>
<th scope="col">User Reference</th>
<th scope="col">Type</th>
<th scope="col">Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
#foreach (var rec in Model.Data)
{
<tr>
<td style="display: none">
#Html.TextBoxFor(m => rec.Id)
</td>
<td>
#Html.CheckBoxFor(m => rec.IsChecked)
</td>
<td>#rec.Created</td>
<td>#rec.UserReference</td>
<td>#rec.Type</td>
<td>#rec.Status</td>
<td>
<input name="submit" type="submit" id="process" value="submit" />
</td>
</tr>
}
</tbody>
</table>
</form>
The issue I have is when I press submit I'm expecting to pass the content of the table into my controller, however when I submit the form the model on my controller is null:
[HttpPost]
public async Task<IActionResult> Index(List<UserData> data)
When I submit the form I expect to have a list of id's and checkbox values either true / false, can someone shed some light into why I'm not able to see this within the post method of the controller?
Found the solution of the following thread, seems switching foreach to for resolved the issue.
I have an ASP.Net MVC website and I want to pass a textbox value from view to controller using URL Action.
Below is my code,
<table class="table table-striped table-bordered table-hover" id="products" width="100%">
<thead>
<tr>
<th>ProductId</th>
<th>Name</th>
<th>ShortName</th>
<th>ProductNamePrefix</th>
<th>Minimum Count</th>
<th>Add Product</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.ProductId)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.ShortName)
</td>
<td>
#Html.DisplayFor(modelItem => item.ProductNamePrefix)
</td>
<td>
#Html.TextBox("MinCount", item.MinimumCount, new {#class = "form-control" + " " + item.ProductId})
</td>
<td>
#if (item.IfExists == true)
{
<div class='isa_success'><i class='fa fa-check'></i></div>
}
#if (item.IfExists == false)
{
<div class='isa_info'><i class='fa fa-plus-circle'></i></div>
}
</td>
</tr>
}
</tbody>
</table>
I want to pass the textbox value in url action method to controller. I am creating a custom class based on the id for textbox but I am not able to retrieve it using javascript or jQuery.
but I am not able to retrieve it using javascript or jQuery
Why not? It's pretty simple.
In the absence of JavaScript, you can't do this with just a link. Instead, you'd need to use a form. So you'd have to wrap each table row in a form element and replace your link with an input type="submit". (And, of course, style it according to your needs.) This would post the values of the contained form elements (including the text box) to the form's action.
This does get a little ugly, since you can't wrap a form around a tr, so you'd have to nest your structure. Something like this:
<table>
<tr>
<td>
<form>
<table><!-- Your 1-row table goes here --></table>
</form>
</td>
</tr>
</table>
The outer tr is what gets repeated for each row of your "table", so each row is actually a single cell containing a nested table which itself has only one row. As I said, a bit ugly. But it gets the job done.
I have an ajax call function. Inside that I'm calling a partial view. This view is for displaying comments. How can I refresh this view using ajax? I don't like json in my context, because my linq queries are set up with models. So these models with partial view should be send to ajax method. Ajax method should replace my div. Note that before ajax call, this view should be rendered at first as the page loads. I am not getting this. What is my fault?
$.ajax({
url: '/Home/Item',
type: 'POST',
data: { itemid: itemid },
success: function (data) {
$('.mycontainer').html(data);
}
});
Controller
public ActionResult Item(int itemid)
{
FoodContext db = new FoodContext();
ViewBag.FoodItems = db.FoodItems.Where(row => row.itemid == itemid);
List<ImageComment> comments = (from user in db.TxtComments
join o in db.Logins on user.username equals o.username
where user.itemid == itemid
select new ImageComment
{
ImageUrl = o.imgurl,
Comment = user.txtcmt,
ImgCmntUrl = user.imgurl,
Cmntdate = user.cmtdate,
Username = user.username,
}).OrderByDescending(x => x.Cmntdate).ToList();
ViewModel vm = new ViewModel { ImageComments = comments };
return PartialView("_Comments", vm);
}
Partial View
#model ViewModel
#foreach (ImageComment comment in Model.ImageComments)
{
<table width="100%" height="152" border="0">
<tr>
<td width="101" rowspan="2" valign="top"><img src="#comment.ImageUrl" width="100%" height="100%" /></td>
<td height="27" colspan="3" valign="middle"><p> #comment.Username Commented On On #comment.Cmntdate</p></td>
</tr>
<tr>
<td colspan="2" rowspan="2"><div style="width:70%;">
#if (#comment.ImgCmntUrl != null)
{
<img src="#Url.Content(comment.ImgCmntUrl)" width="100%" height="100%" />
}
</div>
<div style="background-color:#E3EEFA;width:68%;min-height:50px;padding:5px;">#comment.Comment</div></td>
<td width="209" height="29"> </td>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
<tr>
<td height="23"> </td>
<td>Like this.</td>
<td>Unlike this</td>
<td> </td>
</tr>
<tr>
<td height="23"> </td>
<td width="303"> </td>
<td width="588"> </td>
<td> </td>
</tr>
</table>
}
My view
<div class="mycontainer">
</div>
You could use the jquery load function:
<div class=".mycontainer"></div>
<script>
function ReloadComments(){
$(".mycontainer").load("#Url.Action("Item", new { itemId = Model.Id })");
}
$(function(){
setInterval(ReloadComments, 10000);
ReloadComments();
});
</script>
Your action method and partial view don't need to be edited.
We have did something similar in our project. first of all we have two action methods one is to get the data (doesnot have any view related things) and pass it to other one which have view , it will do nothing but get the input and render view directly.
The context is we have a timer which will call the ajax request in particular interval and get the data pass it to action (which has view) that will update the view in the background.
Hope i made it clear.
Below is my razor code for my table of users and the current add/edit layout
<table class="smalltable" cellpadding="0" cellspacing="0" id="tblUsers">
<thead>
<tr>
<th> </th>
<th>First Name</th>
<th>Last Name</th>
<th>Dept</th>
<th>Assyst Name</th>
</tr>
</thead>
<tbody>
<tr>
<td>#{ Html.BeginForm("AddEditUser", "Home"); }
<input type="submit" value="Add" id="btnSave" name="cmd" class="plain-button" />
</td>
<td>#Html.Editor("Forename")</td>
<td>#Html.Editor("Surname")</td>
<td>#Html.DropDownList("lstDepts")</td>
<td>#Html.Editor("AssystName")
#{ Html.EndForm(); }</td>
</tr>
#foreach (var User in Model)
{
<tr>
<td>#Html.ActionLink("Edit", "AddEditUser", new { id = User.ID }, new { name = "cmd", value = "Edit" })</td>
<td>
#User.Forename
</td>
<td>
#User.Surname
</td>
<td>
#User.Dept
</td>
<td>
#User.AssystName
</td>
</tr>
}
</tbody>
</table>
What i want to achieve is when a edit is pressed, the row that the edit link was on turns into edit boxes, i how to load up the add form with the edit users details (i could use hidden id and set it with querystring) but i wanted to edit in place really
anyone know how to do this or can point me in the right place?
THanks
My form isn't always submitted when I hit the submit button.
On my form I have one submit button. When I first hit the button, the form will submit. But when there's a validation error, the error is shown. But when I fix that error and press the submit button again, the form is not submitted. This will happen if you work with 'normal' speed; if you do everything very slow, then the form will submit.
In the 'normal speed' mode I see in FireBug that there's a request to the server, but my breakpoint in the code is never hit! So I keep on the same page and nothing happens. When I click multiple times (5-10) or I wait a few seconds and then click the submit button, the submit will reach my code.
I am using MVC4 with the .NET 4.5 framework.
I hope someone can help me with this..
EDIT:
This is the code I am talking about.
My html (with razor) code:
<div id="content" class="boxBorder">
<form method="post" action="/Import/ProcessStep" #(Model.UploadFiles ? "enctype=multipart/form-data" : "") id="wizardForm">
<table id="detailsTable" width="550" cellspacing="0" border="0">
<thead>
<tr>
<th class="first">Importwizard
</th>
</tr>
<tr>
<th></th>
</tr>
</thead>
<tfoot>
<tr>
<td></td>
</tr>
</tfoot>
<tbody>
<tr>
<td> </td>
</tr>
<tr>
<td>
<div id="ImportProgressBar">
<ul>
#foreach (var step in Model.StepNames)
{
<li>
<div class="WizardProgressStep">
<img src="#step.Value" class="ProgressStepImage" />
<br />
<span>#step.Key</span>
</div>
</li>
}
</ul>
</div>
<div id="StepTitle">
#Model.StepTitle
<hr />
</div>
<div id="StepContent">
#RenderBody()
</div>
</td>
</tr>
<tr>
<td> </td>
</tr>
<tr>
<td>
<div id="WizardNavigationBox">
#if (Model.HasPreviousButton)
{
<input type="submit" name="PreviousStep" id="PreviousStep" value="Vorige" class="button icon add" />
}
#if (Model.HasNextButton)
{
<input type="submit" name="NextStep" id="NextStep" value="Volgende" class="button icon add saveButton" />
}
</div>
</td>
</tr>
</tbody>
</table>
</form>
</div>
My controller:
[HttpPost]
public ActionResult ProcessStep(FormCollection formCollection)
{
WebMediator mediator = new WebMediator();
ViewResult newStep;
GenericWizardViewModel viewModel;
if (formCollection["NextStep"] != null)
{
ValidateStep(formCollection);
if (ModelState.IsValid)
{
mediator.ProcessStep(formCollection);
newStep = mediator.GetNextStep();
}
else
{
IWizardStep currentStep = mediator.GetCurrentStep();
viewModel = mediator.CreateViewModel(currentStep);
return this.RazorView(currentStep.StepName, viewModel);
}
}
else
{
newStep = mediator.GetPreviousStep();
}
viewModel = newStep.Model as GenericWizardViewModel;
return this.RazorView(newStep.ViewName, viewModel);
}
We finally figured it out.
All our controllers inherit from a custom BaseController class. This BaseController had an trribute with OutputCache on it with a duration set to 10 seconds. Removing this attribute fixed my problem.