I have the following class:
public class NewCommentClass
{
public string ActionName { get; set; }
public object RouteValues { get; set; }
[Required(ErrorMessage = "Comment Required")]
public string Comment { get; set; }
public int? CommentParentID { get; set; }
}
following code in view:
NewCommentClass newCommentClass = new NewCommentClass() { ActionName = "PostComment", RouteValues = new { id = ideaItem.Ideas.IdeaID } };
Html.RenderPartial("~/Views/Shared/NewComment.ascx", newCommentClass);
and NewComment.ascx:
<% # Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<NEOGOV_Ideas.Models.NewCommentClass>" %>
....
<div class="comment-new-container">
<div class="grid_1 alpha item-sidebar">
<p style="padding-top: 0.5em">
<a href="#">
<img src="<% = userAvatar %>" class="profile-photo" alt="Your Profile Picture" width="48"
height="48" /></a>
</p>
</div>
<div class="grid_8 omega">
<div class="comment-body">
<% using (Html.BeginForm(Model.ActionName, "Home", Model.RouteValues, FormMethod.Post, new { id = "FormAddComment", name = "FormAddComment" }))
{ %>
<fieldset>
<% = Html.TextAreaFor(model => model.Comment, htmlAttributes)%>
<% = Html.ValidationMessageFor(model=>model.Comment) %>
<input type="submit" value="<% = postButtonTitle %>" class="small blue awesome noborder" />
</fieldset>
<%} %>
</div>
</div>
<div class="clear">
</div>
</div>
and following post method in controller:
public ActionResult PostComment(int id, string Comment, int? CommentParentID, string referrerUrl)
{
...
}
but this validation does not work correctly.
If I enter data to textarea and click on "Submit" - all ok
But If I just click on "Submit" without data inside - got error message (it's correct), but when I enter data to textarea after this action - error message is hidden, but form is not submited!. If I add Html.ValidationSummary(true) - I one label is hidden, but second is shown.
Why so strange behaviour?
In your Html.BeginForm() command, you create an HtmlAttribute object, and you use it to set the name and id of your textarea to FormAddComment. Because this is the only field in the form, you would need to change your method signature as follows:
[HttpPost]
public ActionResult PostComment(string FormAddComment)
Your current signature doesn't receive anything from the posted form. If you use Fiddler or a similar tool to inspect what is being posted, you will see FormAddComment=[whatever was typed into the textarea] as the body of the POST sent from your browser.
Related
Using the create page I am trying to update two tables using razor page. I create another class where I populated all the properties of both tables to make a joinder. Now my form is not sending data to my defined method, where am i making the mistake?
#page
#model Restaurant.Model.CityBranchJoinder
#{
ViewData["Title"] = "Create";
}
<hr />
<div class="row">
<div class="col-md-4">
#using (Html.BeginForm("SaveRecord","Cities/Create",FormMethod.Post))
{
<h1> Brand ID</h1>
#Html.TextBoxFor(model=>model.BranchID)
<h1> Brand Name</h1>
#Html.TextBoxFor(model=>model.BranchName)
<h1> CityID</h1>
#Html.TextBoxFor(model=>model.CityId)
<h1> CityName</h1>
#Html.TextBoxFor(model=>model.CityName)
<input type="submit" value="Create" class="btn btn-primary" />
}
</div>
</div>
[BindProperty]
public City City { get; set; }
public Branch Branch { get; set; }
public CityBranchJoinder CityBranchJoinder { get; set; }
[HttpPost]
public IActionResult SaveRecord(CityBranchJoinder model)
{
City city= new City();
Branch branch= new Branch();
city.CityId= model.CityId;
city.CityName= model.CityName;
_context.City.Add(city);
_context.SaveChangesAsync();
branch.BranchID= model.BranchID;
branch.BranchName= model.BranchName;
branch.CityId= model.CityId;
_context.Branch.Add(branch);
_context.SaveChangesAsync();
return RedirectToPage("./Index");
}
}
}
I tried changing Cities/Create to Create only but it does not work. Create is my Page Model name but on top I am using another model so that I could post to two tables using one form. But my form does not submit data to my action item.
I have a View where the User can leave a feedback comment in regards to the content video that is playing on the page. Using the following code I am able to manually enter the UserID and ContentID and it saves to the database without problem.
#using (Html.BeginForm("Screencast", "Media", FormMethod.Post, new { id = "form", enctype = "multipart/form-data" }))
{
<div class="row">
<div class="six columns">
<div class="row">
<div class="six columns">
#Html.LabelFor(c => c.FeedbackComment.UserID)
#Html.TextBoxFor(c => c.FeedbackComment.UserID)
</div>
<div class="six columns">
#Html.LabelFor(c => c.FeedbackComment.ContentID)
#Html.TextBoxFor(c => c.FeedbackComment.ContentID)
</div>
<div class="row">
<div class="twelve columns">
#Html.LabelFor(c => c.FeedbackComment.FeedbackString)
#Html.TextAreaFor(c => c.FeedbackComment.FeedbackString)
</div>
</div>
</div>
</div>
</div>
<input type="submit" value="Submit button" class="medium button bottom20"/>
}
However, when the user is on the page before the HTTP post I actually have the related variables in my Model called:
Model.User.UserID
Model.SelectedItem.ContentID
I want to pass these in as hidden fields but when I try to do either:
#HtmlHiddenFor(c => c.FeedbackComment.UserID, #Model.User.UserID)
#HtmlHiddenFor(c => c.FeedbackComment.ContentID, #Model.SelectedItem.ContentID)
or
#HtmlHidden("UserID",#Model.User.UserID)
#HtmlHidden("ContentID",#Model.User.UserID)
Then these values are returned null despite the values being populated before the post. I read about a workaround of putting the input tags in manually but when I did this the #Using.HtmlBeginForm was returning an error of not being set to an instance of an object
Can someone please help me to understand how I can pass these values to the same page using the values I have in the model prior to the post.
Given the following view model (partial):
public class YourViewModel
{
public User User { get; set; }
public SelectedItem SelectedItem { get; set; }
}
You can bind the these properties to a hidden form element. When you post back these properties will still contain their values.
#Html.HiddenFor(x => x.User.UserID)
#Html.HiddenFor(x => x.SelectedItem.ContentID)
Your action method:
public ActionResult YourActionMethod(YourViewModel viewModel)
{
// When you debug here you will see that the values are retained
}
I hope this helps.
I am trying out with very basic MVC project using MVC 3.0 and Razor. Referring the turorial at this link.
I have created a strongly typed view for editing the Contacts using my model class called "Contact".
namespace Practice.Models
{
public class Contact
{
public string firstName;
public string lastName;
public string mobileNumber;
}
}
The "Index" method displays all the contacts using a list type view. When I click on "Edit" link against a contact, it displays the contact details in textboxes using an Edit View.
However, when I submit the Edit form, I am not getting the model values in controller action method. It shows null for each property. What exactly I may be missing here in such simple example?
DirectoryController
[HttpPost]
public ViewResult Edit(Contact model)
{
contactRepository.Update(model);
return View("Details", model);
}
View
#model Practice.Models.Contact
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"> </script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm("Edit","Directory"))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Contact</legend>
#Html.TextBoxFor(m => m.firstName)
#Html.TextBoxFor(m => m.lastName)
#Html.TextBoxFor(m => m.mobileNumber)
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
You are missing { get; set; } on your model properties
I'm trying to check if the combination of typeId & supplementId already exists in my database. So I've added a remoteattribute to my supplementId which does this. My problem is that the validation should trigger on changing either dropdownlist. I kinda fixed this clientside with the javascript on the ddl onchange. But now I'm not able to post my form. When I click the button, it focuses the last dropdownlist but doesn't show any errors and my Post method in the controller doesn't get fired. If I execute a form.submit() in chrome console the method gets called but validation is ignored. Anyone had this issue before?
BTW this code is cleaned to a minimum so labels, errormessages, etc could be missing,
these shouldn't be the issue.
Partial view:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<SupplementTypeClass>" %>
<script src="<%: Url.Content("~/Scripts/jquery-1.5.1.min.js") %>" type="text/javascript"></script>
<script src="<%: Url.Content("~/Scripts/jquery.validate.min.js") %>" type="text/javascript"></script>
<script src="<%: Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js") %>"
type="text/javascript"></script>
<% using (Html.BeginForm("AddEditSupplementType", "Supplement"))
{ %>
<%: Html.ValidationSummary(true)%>
<fieldset>
<legend>
Add type
</legend>
<div class="editor-content">
<div class="editor-label">
<%: Html.LabelFor(model => model.SupplementId)%>
</div>
<div class="editor-field">
<%: Html.DropDownListFor(model => model.SupplementId, new SelectList(ViewBag.Supplements, "SupplementId", "Name", Model.SupplementId), "Select supplement", new { onchange = "$('#ddl').removeData('previousValue');$('#ddl').valid();" })%>
<%: Html.ValidationMessageFor(model => model.SupplementId)%>
</div>
</div>
<div class="editor-content">
<div class="editor-label">
<%: Html.LabelFor(model => model.TypeId)%>
</div>
<div class="editor-field">
<%: Html.DropDownListFor(model => model.TypeId, new SelectList(ViewBag.Types, "TypeId", "Name", Model.TypeId), "Select type", new { id ="ddl" })%>
<%: Html.ValidationMessageFor(model => model.TypeId)%>
</div>
</div>
<div class="editor-buttons">
<input type="submit" value="Save" />
</div>
</fieldset>
<% } %>
Controller:
[HttpPost]
public ActionResult AddEditSupplementType(SupplementTypeClass sup)
{
if (ModelState.IsValid)
{
//code to insert to DB
}
return RedirectToAction("FicheAddEditSupplementType", new { supplementTypeId = sup.supplementTypeId});
}
Class:
public class SupplementTypeClass
{
#region Members
public int SupplementId { get; set; }
[RemoteAttribute("SupplementTypeCheck", "Supplement", AdditionalFields = "SupplementId")]
public int TypeId { get; set; }
#endregion
}
The Remote attribute does Ajax calls using the GET method by default, not POST.
Make your you specificy the POST method in your model
[RemoteAttribute("SupplementTypeCheck", "Supplement", AdditionalFields = "SupplementId", HttpMethod="POST")]
I have the following HTML on my displayed form
<fieldset>
<legend>Edit User Roles</legend>
<ul>
<% foreach (string role in (string[]) ViewData["roles"]){ %>
<li>
<div id="Div4" class="grid_6">
<div id="Div5" class="grid_2 alpha" style="font-weight: bold;">
<%= Html.CheckBox("role." + role, Roles.IsUserInRole(Model.UserName, role))%>
</div>
<div id="Div6" class="grid_3 omega" style="font-family: Verdana; font-size: 10pt;">
<label for="role.<%: role %>">
<%: role %></label><br />
</div>
</div>
</li>
<% } %>
</ul>
</fieldset>
I have the following code in my Controller
[HttpPost]
public ActionResult EditUser( string id, bool approved )
{
int i = Request.Form.Keys.Count
foreach (string key in Request.Form.Keys)
{
if (key.StartsWith( "role." ))
{
// Do something
}
}
MembershipUser membershipUser = Membership.GetUser( id );
return View( membershipUser );
}
If I break the code and explore, I find that the Request.Form.Keys.Count = 0, although there should be at least 4 keys created with "role." as a prefix from four checkboxes displayed on the form.
What am I not understanding here?
Request.Form.Keys.Count = 0 could have two possible explanations:
No value was sent in the POST body
You used some special content type such as for example application/json instead of application/x-www-form-urlencoded (could happen if you play with AJAX)
I would recommend you using FireBug to see exactly what's contained in the POST request and if there are any values. You haven't shown the form definition neither how you are submitting it. If you are POSTing with AJAX maybe there's where the problem lies.
Here's an example of how a valid request might look like in FireBug: