I need to submit data via AJAX, but only an empty string reaches the ActivateUser Method.
Here is the Markup
#model String
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Benutzer aktivieren</h4>
</div>
<div class="modal-body">
<div id="activateresult"></div>
<div style="display: none" id="activateUserSuccess" class="alert alert-success">Der Benutzer konnte erfolgreich aktiviert werden :)</div>
<div style="display: none" id="activateUserFailure" class="alert alert-danger">Leider konnte der Benutzer nicht aktiviert werden :(</div>
<div class="list-group">
#foreach (var item in #deactivatedUsers) {
using (Ajax.BeginForm("ActivateUser", "Settings", new AjaxOptions() {
HttpMethod = "POST",
OnSuccess = "activateSuccess(response)",
OnFailure = "activateFailure(jqXHR, textStatus, errorThrown)",
UpdateTargetId = "activateresult"
}, new {
#class = "list-group-item"
})) {
<h4>
#item.Username
#Html.Hidden("Username")
</h4>
<input class="btn btn-success" type="submit" name="#item.ID" value="Aktivieren" />
}
}
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal">Fertig</button>
</div>
</div>
</div>
And here is the Controller method
[HttpPost]
public ActionResult ActivateUser(string username) {
try {
customerModel.ActivateUser(username);
return new JsonResult() { Data = true };
} catch (Exception ex) {
return new JsonResult() { Data = false };
}
}
You can the the whole code on github
What am I doing wrong?
Try switching this:
#Html.Hidden("Username")
to this:
#Html.Hidden("username", item.Username)
The parameter to your action is lowercase, and I believe that it is case-sensitive.
Furthermore, that second parameter I am passing in is the value parameter. Without that, I believe framework is going to look for a Username property on the Model. But here you have a username property on item. So the framework wouldn't be able to find the username even with the lowercase correction. You need to explicitly pass in the value in this case.
You can verify you're creating the right thing by looking at the generated HTML in your browser. You want to make sure that your input field is actually named username and that its value is actually the current user's username.
Related
I would like to know how to pass values from a textbox and selected value to a controller. At the moment I am able to get to my controller but the value of what was entered in textbox and value of what was selected in dropdown is always null by the time it reaches the controller and I am not sure why.Perhaps I should be doing this using the ViewData instead?
my textbox, dropdown and search button
<div id="cc" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">Advanced Search</h4>
</div>
#using (Html.BeginForm("AdvancedFilteredSearch", "FilteredSearch", FormMethod.Get, new { id = "frmAdvancedSearch", #class = "form-horizontal", role = "form" }))
{
<div class="modal-body">
<div class="dropdown">
<br />
<select class="form-control" id="condition" name="condition">
<option value="">Select Search Conditions</option>
<option value="1">Between</option>
<option value="2">Or</option>
</select>
</div>
<div>
<i class="fas fa-envelope prefix grey-text"></i>
<input type="text" id="search" name="search" class="form-control validate" placeholder="Type here">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Clear Filters</button>
<button type="button" onclick="location.href = '#Url.Action("FilteredSearch", "FilteredSearch")'"class="btn btn-primary">Search</button>
</div>
}
</div>
</div>
</div>
**My Controller Method**
public ActionResult AdvancedFilteredSearch(FormCollection collection)
{
string value = Convert.ToString(collection["search"]);
string value = Convert.ToString(collection["condition"]);
return View(db.marketingdbclients_dataTable.Where(a => a.ClientId < 500));
}
Never used FormCollection class before. But as far as i rememeber, when you submit your form you can simply do:
[HttpPost]
public ActionResult AdvancedFilteredSearch(int condition, string search )
{
return View(db.marketingdbclients_dataTable.Where(a => a.ClientId < 500));
}
Your variables "condition" and "search" should be the same with id of your HTML form-element. And don't forget about HttpPost attribute before your method.
I'm trying to rerender the partialview ONLY in my modal, after the ajax request.
But when I get the response everything is rerendered and the only thing showing is the partialview..
PartialView:
#{
var bidModel = new BidModel();
}
<div>
<div class="row">
#if (ViewBag.Message != null)
{
<div class="alert alert-success">#ViewBag.Message</div>
}
</div>
<span class=" alert-danger">
#Html.ValidationSummary()
</span>
<div class="form-group">
<input name="Bidder" asp-for="#bidModel.Bidder" value="#User.Identity.Name" type="hidden" />
<input name="AuctionId" asp-for="#bidModel.AuctionId" type="hidden" id="auctionId" />
<label asp-for="#bidModel.Amount" />
<input name="Amount" asp-for="#bidModel.Amount" />
</div>
</div>
Controller:
public async Task<IActionResult> AddBid(BidModel Bid)
{
var result = await _bidBusinessInterface.CreateBidAsync(Bid, Bid.AuctionId);
if (result)
{
ViewBag.Message = "Bud lagt!";
}
else
{
ViewBag.Message = "Bud förlågt!";
}
return PartialView("_BidCreatorPartial");
}
And then we have the modal where i want to rerender the partialview:
<div class="modal fade" id="bidModal" tabindex="-1" role="dialog" aria-labelledby="bidModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="bidModalLabel">Lägg bud</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form asp-action="AddBid" asp-controller="Home" method="POST" data-ajax="true" data-ajax-update="frmBid">
<div id="frmBid">
<partial name="_BidCreatorPartial" model="#bidModel"/>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Avbryt</button>
<button type="submit" class="btn btn-primary">Spara</button>
</div>
</form>
</div>
</div>
</div>
</div>
As I said, what I want to accomplish is to rerender the form, so that the message can be shown in the modal.
What happens is it renders a whole white page with only the form and the message.
You didn't actually post your form itself, but my best guess is that you're just doing a standard old HTML form post. That's always going to cause the page to change, and then since you're only returning a partial view, and not a full view, your page gets replaced with just that snippet of HTML.
What you want requires AJAX. You need to catch the submit event on the form, and instead of letting it go as normal, you make an AJAX request with the form data serialized. Then, in the success callback of your AJAX request, you'll need to query the element you want to replace the HTML of from the DOM and change its innerHTML value to what's returned from the AJAX request.
Since an ASP.NET Core project comes with jQuery out of the box, I'm going to assume you can use that:
$('#MyForm').on('submit', function (e) {
e.preventDefault();
var $form = $(this);
$.ajax({
url: $form.attr('action'),
method: 'post',
data: $form.serialize(),
success: function (html) {
$('#frmBid').html(html);
}
});
});
I have a partial view inside another partial view which, when first running the application loads as expected, but when you click to reload the view to push a model into it, it then renders as it's own completely separate view as if it weren't a partial.
I'm calling it inside an Ajax Form like so (On the Action link click, the _GetSearchModal method):
<div id="modelSearch">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
<i class="fa fa-search"></i> Search by Model / Manufacturer
</h3>
</div>
<div class="panel-body">
#using (Ajax.BeginForm("_GetSearch", "Home", new AjaxOptions() {UpdateTargetId = "modelSearch"}))
{
#Html.AntiForgeryToken()
<div class="input-group">
#Html.TextBox("search", null, new {id = "name", #class = "form-control", placeholder = "Please enter a manufacturer or model"})
<span class="input-group-btn">
<button id="search" class="btn btn-default" type="submit"><i class="fa fa-search"></i></button>
</span>
</div>
if (Model != null)
{
<div id="searchResults" class="fade-in two">
#foreach (var s in Model)
{
<div class="result">
#switch (s.ResultType)
{
case "Man":
#s.Manufacturer
break;
case "Mod":
#Html.ActionLink(s.Manufacturer + Html.Raw(s.Model), "_GetSearchModal", "Home", new {id = s.MachineId}, new {toggle = "modal", data_target = "#MachineModal"})
<img src="~/Images/General/Tier/#(s.TierId).png" alt="Tier #s.TierId"/>
break;
}
</div>
}
</div>
}
}
</div>
</div>
</div>
<!-- Product Modal -->
<div class="modal fade" id="MachineModal" tabindex="-1" role="dialog" aria-labelledby="MachineModalLabel">
#Html.Partial("_SearchModal", new MachineModal())
</div>
And the view itself should load a different view model (MachineModal):
#model SpecCheck.Portals.Web.UI.ViewModels.MachineModal
#if (Model != null)
{
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="MachineModalLabel">#Model.Manufacturer #Model.Model</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-6">
<img src="~/Images/#Model.Manufacturer/logo.png" alt="#Model.Manufacturer" /><br />
Wiki
</div>
<div class="col-md-6">
#Model.Catagory1 | #Model.Category2<br /><br />
<span class="modal-em">Region: </span> #Model.Region<br />
<span class="modal-em">Status: </span>#Model.Status<br />
<span class="modal-em">Spec Date: </span>#Model.SpecDate
</div>
</div>
</div>
<div class="modal-footer">
View
Quick Compare
Compare
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
}
And the action to do this in the "Home Controller" is:
public ActionResult _GetSearchModal(string machineId)
{
using (var db = new SpecCheckDbContext())
{
MachineModal machine = new MachineModal();
var searchHelper = new SearchHelper(db);
//Get Machine Details
var dbResults = searchHelper.SearchModal(Convert.ToInt32(machineId));
machine.Model = dbResults.Model;
machine.Catagory1 = dbResults.Catagory1;
machine.Category2 = dbResults.Category2;
machine.Manufacturer = dbResults.Manufacturer;
machine.Region = dbResults.Region;
machine.SpecDate = dbResults.SpecDate;
machine.Status = dbResults.Status;
machine.MachineId = dbResults.MachineId;
machine.ManufacturerId = dbResults.ManufacturerId;
var model = machine;
return PartialView("_SearchModal", model);
}
}
First thing I checked was the scripts, they're all in place when the layout page loads so it's not a script issue. Not sure what to change to even try at this point so any suggestions welcome.
In the ajax form:
_GetSearch => _GetSearchModal(name of the action)
Try to return machine to the partial view? Maybe see in the View hierarchy, is there is second _SearchModal partial view, that gets returned?
net mvc 5 application and for this I use bootstrap because it looks fine.
I don't want to use for an input and a searchbutton the
#using (Html.BeginForm("...
Can I control the html tags without this from my controller. For example here is my index.cshtml
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="container">
<div class="row">
<h2>Suche</h2>
<div id="custom-search-input">
<div class="input-group col-md-12">
<input type="text" class=" search-query form-control" placeholder="Search" />
<span class="input-group-btn">
<button class="btn btn-danger" type="button">
<span class=" glyphicon glyphicon-search"></span>
</button>
</span>
</div>
</div>
</div>
</div>
I want if I click on the Searchbutton I get a message with the text from the inputfield.
Here is the Controller:
public ActionResult Search(string value)
{
//listofUsers is a arraylist of all users that found^^
return View(listofUsers);
}
How I can do this? :)
Add a div to show the result:
<div id="custom-search-input">
<div class="input-group col-md-12">
<input type="text" class=" search-query form-control" placeholder="Search" />
<span class="input-group-btn">
<button class="btn btn-danger" type="button">
<span class=" glyphicon glyphicon-search"></span>
</button>
</span>
</div>
</div>
<div class="custom-search-result"></div>
Then in a script tag or a linked js file:
$(document).ready(function () {
$('.custom-search-input').each(function () {
var sinput = $(this);
var svalue = sinput.find('input');
var sresult = sinput.next('.custom-search-result');
sinput.find('button').click(function () {
$.ajax({
url: '/ControllerName/Search?value=' + svalue.val(),
type: 'GET'
}).done(function (result) {
sresult.html(result);
});
});
});
});
This is a basic example with no error handling.
First I highly recommend reading Philip Walton (Google) - Decoupling your HTML, CSS and Javascript, it's extremely good.
Here how I would use MVC to it's full potential.
Model:
// Extensible Programming
// Using a string limits additional features
// Future proofing via a class that takes 2 minutes to create
public class GlobalSearch
{
public string SearchTerms { get; set; }
}
View:
#Model GlobalSearch
<div class="container">
<div class="row">
<h2>Suche</h2>
<div id="custom-search-input">
#using (Html.BeginForm("Search"))
{
<div class="input-group col-md-12">
#Html.TextBoxFor(m => m.SearchTerms, new {
#class="search-query form-control",
placeholder="Search" })
<span class="input-group-btn">
<button class="btn btn-danger" type="button">
<span class=" glyphicon glyphicon-search js-form-submit"></span>
</button>
</span>
</div>
}
</div>
</div>
</div>
Controller:
// Strongly Typed Class is Returned
public ActionResult Search(GlobalSearch search)
{
return View(listofUsers);
}
The following script will require this fantastic script called form2js which correctly converts any strongly-typed forms generated by MVC (arrays, lists etc) into Json that will be ModelBinded correctly.
$(document).ready(function() {
('.js-form-submit').on('click', function() {
var $form = $(this).closest('form');
var json = form2js($form);
var ajaxSettings = {
url: $form.attr('action'),
type: $form.attr('method'),
data: json,
contentType: "application/json",
}
$.ajax(ajaxSettings)
.done()
.always()
.fail();
});
});
Of course this could be easily abstract into it's own javascript class/namespace that returns the promise and reusable on any form that simply has a button with the class js-form-submit instead of continually rewriting $.ajax over and over again each time for different forms.
I'm fairly new to asp .net MVC, I've got a modal wish accepts a username, email address, comments, and also has a submit button. I'm looking create the submit functionality such that when it's pressed it'll send an email.
I've had passed experience sending emails in c# no problem, the troubles I'm having is linking the two together.
<div class="modal fade" id="contact" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<form class="form-horizontal">
<div class="modal-header">
<h4>Contact Tech Site</h4>
</div>
<div class="modal-body">
<div class="form-group">
<label for="contact-name" class="col-lg-2 control-label">Name:</label>
<div class="col-lg-10">
<input type="text" class="form-control" id="contact-name" placeholder="Full Name">
</div>
</div>
<div class="form-group">
<label for="contact-email" class="col-lg-2 control-label">Email:</label>
<div class="col-lg-10">
<input type="email" class="form-control" id="contact-email" placeholder="you#example.com">
</div>
</div>
<div class="form-group">
<label for="contact-msg" class="col-lg-2 control-label">Message:</label>
<div class="col-lg-10">
<textarea class="form-control" rows="8"></textarea>
</div>
</div>
</div>
<div class="modal-footer">
<a class="btn btn-default" data-dismiss="modal">Close</a>
<button class="btn btn-primary" type="submit">Send</button>
</div>
</form>
</div>
</div>
</div>
Email Code
var SMTP_USERNAME = User.EmailUsername;
var SMTP_PASSWORD = EncryptionHelper.Decrypt(User.EmailPassword);
Mail.Subject = Subject;
Mail.Body = EmailText;
foreach (var to in SelectedUsers)
{
foreach (var contactMethod in to.ContactMethods.Where(x => x.Primary && x.Channel == ContactMethod.Channels.Email))
{
Mail.To.Add(contactMethod.Value);
}
}
Mail.From = new MailAddress(SMTP_USERNAME, User.FullName());
//Server
var HOST = unitOfWork.SettingRepository.GetString(KnownKeys.SMTPServer);
//Port
var PORT = int.Parse(unitOfWork.SettingRepository.GetString(KnownKeys.SMTPPort));
// Create an SMTP client with the specified host name and port.
var emailSent = false;
using (SmtpClient client = new SmtpClient(HOST, PORT))
{
// Create a network credential with your SMTP user name and password.
client.Credentials = new System.Net.NetworkCredential(SMTP_USERNAME, SMTP_PASSWORD);
// Use SSL when accessing Amazon SES. The SMTP session will begin on an unencrypted connection, and then
// the client will issue a STARTTLS command to upgrade to an encrypted connection using SSL.
client.EnableSsl = true;
// Send the email.
try
{
client.Send(Mail);
emailSent = true;
}
catch (Exception ex)
{
MessageBox.Show("Error message: " + ex.Message);
}
}
Create a model -
public class EmailViewModel
{
public string Username { get; set; }
public string Email { get; set; }
public string Comments { get; set; }
}
And then create your controller -
public class HomeController : Controller
{
public ActionResult GetEmailForm()
{
return View();
}
public ActionResult SubmitEmail(EmailViewModel model)
{
var result = SendEamil(model);
return View();
}
private bool SendEamil(EmailViewModel model)
{
// Use model and send email with your code.
return true;
}
}
Basically GetEmailForm action will return you a view with form -
#model MvcApplication1.Controllers.EmailViewModel
#{
ViewBag.Title = "GetEmailForm";
}
<h2>GetEmailForm</h2>
<link href="../../Content/bootstrap.css" rel="stylesheet" />
#using (Html.BeginForm("SubmitEmail", "Home", FormMethod.Post))
{
<div id="contact">
<div class="modal-dialog">
<div class="modal-content">
<form class="form-horizontal">
<div class="modal-header">
<h4>Contact Tech Site</h4>
</div>
<div class="modal-body">
<div class="form-group">
<label for="contact-name" class="col-lg-2 control-label">Name:</label>
<div class="col-lg-10">
#Html.TextBoxFor(m => m.Username, new { #placeholder = "Full Name"})
</div>
</div>
<div class="form-group">
<label for="contact-email" class="col-lg-2 control-label">Email:</label>
<div class="col-lg-10">
#Html.TextBoxFor(m => m.Email, new { #placeholder = "you#example.com"})
</div>
</div>
<div class="form-group">
<label for="contact-msg" class="col-lg-2 control-label">Message:</label>
<div class="col-lg-10">
#Html.TextAreaFor(m => m.Comments, new { #placeholder = "Comments"})
</div>
</div>
</div>
<div class="modal-footer">
<a class="btn btn-default" data-dismiss="modal">Close</a>
<button class="btn btn-primary" type="submit">Send</button>
</div>
</form>
</div>
</div>
</div>
}
When you enter data and click on submit, it will post the viewmodel with data to SubmitEmail action of same controller.
Output of the page is as shown below, sorry for styles, i have no time so removed some of the styles.
When you enter data and click on submit, you get data as shown below -
Once you have the data, you can use that in your private method SendEmail (which will have your code) to send email.
Check the MSDN site for information on how to create a form, it will get submitted when the user presses the submit button. Back in yoru controller add a second version of your method with the HttpPost attribute and give it a parameter instance of your model, MVC will take care of the mapping for you. See BUILDING ASP.NET MVC FORMS WITH RAZOR for more details.
Call a action method From your Email Controller thru a ajax call.From the below Code Snippet you will get an idea how to do it.
$('#btnSubmit').on('click', function () { //Ur Button
$.ajax({
type: "POST",
url: "/EmailController/SendEmailAction",
data: "{Email:" + $("#contact-email").val() +"}", // Reading from extboxes and Converting to JSON for Post to EmailController Action
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(result) {
//alert message
//Close the Modal
}
});
});
And In C# level in youecontroller
public JsonResult _SendEmail(EmailViewModel model)
{
//Here your code to send Email
}
I hope now you will get an idea how to go about it.
I think you do not require a form and submit button to send an email from a bootstrap modal.