I'm using ASP.NET Core 2 MVC and I have a Controller with a Post action method as such:
[HttpPost]
[Produces("application/json")]
public async Task<IActionResult> PostObject([FromForm] ObjectViewModel bjectViewModel)
{
if (!ModelState.IsValid) return BadRequest(ModelState);
//EF code
return Ok(object);
}
My view has the following code:
//View code...
<form asp-action="PostObject" data-ajax="true" data-ajax-method="POST" data-ajax-success="OnSuccess" data-ajax-failure="OnFailure">
#Html.HiddenFor(x => x.VolumeID)
<label asp-for="EAN" class="control-label"></label>
<input asp-for="EAN" id="TextBoxEAN" class="form-control" value="" maxlength="13" autofocus />
<span asp-validation-for="EAN" class="text-danger"></span>
</form>
//More view code...
//This contais ajax stuff
#section Scripts {#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script>
function OnSuccess(result) {
console.log(result);
}
function OnFailure(result) {
alert(result);
}
</script>
I can perform the POST action correctly, but instead of executing the OnSuccess method, it just displays the returned JSON object.
I think this has something to do with referencing ajax-unobtrusive, but I think that is taken care of automatically.
Can someone point me in the right direction?
Related
I feel like this should be pretty simple, but how can I access the Form POST value collection from a dynamic form (basically a standard HTML form, not using EditForms)?
I call this to render the form:
public async Task<string> GetAgencyForm()
{
return await _httpClient.GetStringAsync($"form/create/");
}
I place it in the page like this:
protected override async Task OnInitializedAsync()
{
var content = await agencyFormService.GetAgencyForm();
renderFragment = builder =>
{
builder.OpenElement(1, "p");
builder.AddContent(2, new MarkupString(content));
builder.CloseElement();
};
base.OnInitialized();
}
The form renders like this:
<form id="AgencyForm" method="post">
<label for="Name">Name</label>
<input id="Name" name="Name" value="">
<button type="submit" name="submit" value="submit">Submit</button>
</form>
Upon submit, how would I access the "Name" value? Also, the form parameter may change depending on some parameters. How can I get the whole collection of values?
Here is the model:
public class UserModel()
{
public string UserName{get;set;}
public string UserPassword{get;set;}
public string UserSource{get;set;}
}
Here is the front-end:
#model Sample.Models.UserModel
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<form asp-controller="Login" asp-action="LoginIn.html" method="post">
<div>
<h3>Name</h3>
<span asp-validation-for="UserName"></span>
</div>
<input asp-for="UserName" placeholder="Your username" />
<div>
<h3>Password</h3>
<span asp-validation-for="UserPassword"></span>
</div>
<input asp-for="UserPassword" placeholder="Your password" type="tel" />
<button type="submit">Login in</button>
</form>
The front-end is a Partial View. It is referenced like this:
#await Html.PartialAsync("/Views/Contact/LoginIn.cshtml", new Sample.Models.UserModel() { UserSource = "From website" })
And here is the controller:
[HttpPost]
[ValidateAntiForgeryToken]
[Route("LoginIn.html")]
public IActionResult LoginIn(Sample.Models.UserModel)
{
if (ModelState.IsValid)
{
}
return Redirect();
}
Well, when the form submitted, the controller only can get the UserName/UserPassword but can't get the UserSource unless I add a
<input asp-for="UserSource" />
into front-end.
I don't want to show the UserSource to the user in the front-end(even hide it by CSS).
How can I solve this problem? Thank you.
You can use ajax to post form,here is a demo:
TestFormAction:
public IActionResult TestForm() {
UserModel u= new UserModel { UserSource = "111" };
return View(u);
}
LoginController:
public IActionResult Index()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
[Route("Login/LoginIn.html")]
public IActionResult LoginIn(UserModel u)
{
if (ModelState.IsValid)
{
}
return Ok();
}
TestForm.cshtml:
<form id="myForm" method="post">
<div>
<h3>Name</h3>
<span asp-validation-for="UserName"></span>
</div>
<input asp-for="UserName" placeholder="Your username" />
<div>
<h3>Password</h3>
<span asp-validation-for="UserPassword"></span>
</div>
<input asp-for="UserPassword" placeholder="Your password" type="tel" />
<button type="submit">Login in</button>
</form>
#section scripts{
<script>
$('#myForm').submit(function (event) {
event.preventDefault(); // avoid to execute actual form submit.
var model = {};
model.UserName = $("#UserName").val();
model.UserPassword = $("#UserPassword").val();
model.UserSource =#Model.UserSource;
var token = $('input[name="__RequestVerificationToken"]').val();
$.ajax({
url: '#Url.Action("LoginIn.html", "Login")',
type: 'POST',
data: model,
headers: { "RequestVerificationToken": token },
success: function (data) {
window.location.href = "/Login/Index";
}
});
});
</script>
}
result:
Child model binding is not working properly on Ajax post call in .Net core controller method
I am using below model -
public class UserViewModel
{
public UserViewModel()
{
UserAttribute = new CAMPv2.Models.AutoPoco.UserAttribute();
}
public UserAttribute UserAttribute { get; set; }
}
public class UserAttribute
{
[JsonPropertyName("FirstName")]
public string FirstName { get; set; }
}
Below is the Ajax call -
#using User.Models
#model UserViewModel
#{
ViewData["Title"] = "UserDetails";
}
<form class="kt-form" id="kt_form">
<div class="kt-wizard-v3__content" data-ktwizard-type="step-content" data-ktwizard-state="current">
<div class="kt-form__section kt-form__section--first">
<div class="form-group row required">
<label for="FirstName" class="col-md-3 col-form-label k-font-bold text-md-right control-label">First Name</label>
<div class="col-6">
<input type="text" class="form-control" name="FirstName" placeholder="" required asp-for="UserAttribute.FirstName">
</div>
</div>
</div>
<div class="btn btn-brand btn-md btn-tall btn-wide btn-bold btn-upper" data-ktwizard-type="action-submit" id="btnSubmit">Submit</div>
</div>
</form>
<script>
$("#btnSubmit").click(function () {
var formData = $("#kt_form").serialize();
alert(formData);
$.ajax({
url: "/User/CreateUser/",
data: formData,
type: "POST",
dataType: "json",
success: function (result) {
if (result.success) {
alert('data submitted successfully');
}
},
error: function (result) {
alert('failed to submit data');
},
});
});
</script>
Below is action method -
[HttpPost]
public ActionResult CreateUser(UserViewModel model)
{
try
{
return Json(new { success = true, result = model, errorMessage = "" });
}
catch (WebException ex)
{
return Json(new { success = false, errorMessage = ex.Message });
}
}
Model values are null. Can anyone please let me know what i am missing here? Ajax post call is returning model to action method with null values.
Model values are null. Can anyone please let me know what i am missing here? Ajax post call is returning model to action method with null values.
As far as I know, if you use $("#kt_form").serialize() it will serialize the form into from data according to input tag's name attribute.
But you have set the input tag's name to FirstName. That means the asp.net core model binding will bind the value to FirstName property. But the value is used for UserAttribute's FirstName not the viewmodel's FirstName. This is the reason why your model binding result is null.
To solve this issue, I suggest you could try to use asp.net core tag helper to help you generate the input tag name or you could modify the name property to UserAttribute.FirstName.
You could modify the input as below:
<input type="text" class="form-control" placeholder="" required asp-for="#Model.UserAttribute.FirstName">
Detail view codes:
<form class="kt-form" id="kt_form">
<div class="kt-wizard-v3__content" data-ktwizard-type="step-content" data-ktwizard-state="current">
<div class="kt-form__section kt-form__section--first">
<div class="form-group row required">
<label for="FirstName" class="col-md-3 col-form-label k-font-bold text-md-right control-label">First Name</label>
<div class="col-6">
<input type="text" class="form-control" placeholder="" required asp-for="#Model.UserAttribute.FirstName">
</div>
</div>
</div>
<div class="btn btn-brand btn-md btn-tall btn-wide btn-bold btn-upper" data-ktwizard-type="action-submit" id="btnSubmit">Submit</div>
</div>
</form>
Result:
I have two Views with two different post method in different Controllers. Both methods are used to export data to an Excel file.
Here is my code structure:
[System.Web.Mvc.HttpPost]
public ActionResult upload(HttpPostedFileBase file)
{
// code for this action
ExportToExcel(dd); // export from dataset
}
public void ExportToExcel(DataSet dd)
{
// Code to export
}
My View page code looks like:
<html>
<body>
#using (#Html.BeginForm("upload", "Test", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
<input type="file" name="file" id="files" multiple="multiple" />
<input type="submit" class="btn btn-lg btn-primary" value="Export Excel" name="submit" />
}
</body>
</html>
I have a second post method in another controller that looks basically the same as the above code, with only slight differences.
How can I merge the two post methods into one, and use to export?
I do have three buttons in my view. So now I want two buttons to post back and the third button to perform some jquery. How to do this. Like how to make the third button not to post back and perform some jquery actions.
Thanks
You can do this like
<form id="myForm">
<%-- form data inputs here ---%>
<button id="Postback">Postback</button>
<button id="JavaScript">JavaScript</button>
</form>
and in javascript
<script type="text/javascript">
$("#Postback").click(function() {
var form = $("form#myForm");
form.attr("action", "#Url.Action("action","MyController")");
form.submit();
});
$("#JavaScript").click(function() {
Do your javascript something.
});
</script>
In HTML the tag button has the attibute type:
To post back data (submit a form) you must set type to submit (this is default value, so you may drop the type attribute at all).
To perform some javascript actions you must set type to button.
In two different submit buttoms use same name and different values:
#using (Html.BeginForm("Login", "Home")
{
<label for="login">Login:</label>
#Html.TextBox("login", Model.Login)
<label for="password">Password:</label>
#Html.Password("password", "")
<button type="submit" name="what" value="login">Log in</button>
<button type="submit" name="what" value="register">Register</button>
<button type="button" id="facebook">Facebook authentication</button>
}
<script>
$(function() {
// Perform jquery action.
$('#facebook').click(...);
});
</script>
In controller:
public ActionResult Login(string login, string password, string what)
{
if (what == "login")
. . .
else if (what == "register")
return RedirectToAction("Register", "Home");
}