Accessing Form Post Values in Blazor Webassembly - asp.net-core

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?

Related

How to process forms in ASP.NET Core with unknown fields

I want to create an Http post method that will be able to process html forms of different inputs.
[HttpPost]
public async Task<IActionResult> Create(string content)
{
// process content here.
return View("Success");
}
My method should be able to support this form
<form action="url" method="POST">
<input type="text" name="firstName">
<input type="text" name="lastName">
<button type="submit">Submit</button>
</form>
as well as this form
<form action="url" method="POST">
<input type="text" name="name">
<input type="text" name="surname">
<input type="text" name="age">
<button type="submit">Submit</button>
</form>
How can I modify my method so that the content will be populated for both of these cases?
To process forms with unknown fields, you can use the FormCollection type as a parameter in the Create method. The FormCollection type represents a collection of keys and values that are sent as the HTTP request body when the form is submitted. You can use this type to capture all the form data, regardless of the number or names of the fields.
To access the form data, you can use the formData object. For example, you can access a field with the name "firstName" using the following syntax: formData["firstName"].
PdfController.cs:
public class PdfController: Controller
{
[HttpPost]
public IActionResult Create(IFormCollection formData)
{
// process form data here
var surName= formData["surname"].ToString();
return View("Create", (FormCollection)formData);
}
}
Form:
<form action="/pdf/create" method="POST">
<input type="text" name="name">
<input type="text" name="surname">
<input type="text" name="age">
<button type="submit">Submit</button>
</form>
Create.cshtml:
#model FormCollection
<h1>Form Data</h1>
<table>
#foreach (var key in Model.Keys)
{
<tr>
<td>#key</td>
<td>#Model[key]</td>
</tr>
}
</table>
View:
How can I modify my method so that the content will be populated for
both of these cases?
Well, based on your scenario and requirement,we have two option other than [FormBody] pattern,to deal with completely dynamic value, we can use IFormCollection and a Dictionary.
Our goal is to handle any dynamic data which we will finally add into our Dictionary using its Key and Value.
Completely Dynamic Form Request Example:
[HttpPost]
public IActionResult Create(IFormCollection dynamicData)
{
var dynamicFormDataDictionary = new Dictionary<string, object>();
foreach (var item in dynamicData)
{
dynamicFormDataDictionary.Add(item.Key, item.Value);
dynamicFormDataDictionary.Remove("__RequestVerificationToken");
}
return View("DynamicOutput", dynamicFormDataDictionary);
}
Note: We cannot use FormCollection because it will encounter runtime exception as it has Interface of IFormCollection type. .
Bind Dynamic Data And Display in View:
Controller:
public IActionResult DynamicOutput()
{
return View();
}
View:
#model Dictionary<string, object>
<h4>Dynamic Data</h4>
<table class="table">
#foreach (var key in Model.Keys)
{
<tbody>
<tr>
<th>
#key
</th>
<td>
#Model[key]
</td>
</tr>
</tbody>
}
</table>
Output:
Alternative Way:
We have another way, which is using Request.Form but here we need to define our data fields. In following way we can get the data:
var input1 = Request.Form["firstName"].GetValue();
var input2 = Request.Form["name"].GetValue();
Note: Point to remember, in this way, let's say, you have two request from we would define all the property together and allow null-value. Therefore, we would get our desired value from one request form while other we would remain empty.

Changing attributes of HTML element in server-side code in Razor Pages

I want to be able to access and modify attributes of HTML elements of a page in my server side code (I am using ASP.NET Core Razor Pages 6.0).
For example: a .cshtml file, I have a simple element like this:
<div class="mb-3 mt-3">
<label asp-for="User.firstname" class="form-label">First Name:</label>
<input asp-for="User.firstname" class="form-control" placeholder="First Name">
</div>
How do I access & change attributes of the above <input> element inside the OnGet or OnPost server-side methods?
I need to do so as I want to add a class to that <input> element, or make it read-only (depending on certain conditions in my server code).
In older versions of .NET, I believe this was possible by giving an HTML element an ID, and writing runat="server". Then, one could access the element in the code-behind via its ID and change its attributes. How is this done now in Razor Pages?
Should I not be able to do the same because of the asp-for tag helper which I used inn my code above? But how?
Thank you for your help!
you can achieve sending Value to the server with
This at razor page:
<form method="post">
<div class="form-group">
<input name="title" class="form-control" placeholder="Type title here.." />
<button type="submit" class="btn btn-primary">Post</button>
</form>
This at Model Page
public async Task<IActionResult> OnPostAsync(string title)
{
//do your stuff
}
Put breakpoint at public async Taks and viola.
I believe this should do the trick. You can change it for yourself.
Here is a whole working demo you could follow:
Model
public class User
{
public string firstname { get; set; }
}
Page(.cshtml file)
#page
#model IndexModel
<form method="post">
<div class="mb-3 mt-3">
<label asp-for="User.firstname" class="form-label">First Name:</label>
<input asp-for="User.firstname" class="form-control" placeholder="First Name">
</div>
<input type="submit" value="Post"/>
</form>
PageModel(.cshtml.cs file)
1.For model binding of the element, one way is that you can use [BindProperty]:
public class IndexModel : PageModel
{
[BindProperty]
public User User { get; set; }
public void OnGet()
{
}
public void OnPost()
{
//do your stuff.....
}
}
2.The second way is that you can add parameters like below:
public class IndexModel : PageModel
{
public User User { get; set; }
public void OnGet()
{
}
public void OnPost(User User)
{
}
}

Ajax success method not firing

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?

How to use buttons in MVC for different purposes

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");
}

How do I pass the value to Controller from View without Creating any Object for Model in View in ASP.NET MVC4?

I am new to ASP.NET MVC4 With Entity Framework. I just want to pass the value from View to Controller, I am unable to get it. Please help me to get it. Thanks in advance.
This is my View code:
<form id="changepassword" method="post" action="#Url.Action("Change", "ChangePassword")">
<input type="password" value="currentpswd" class="form-control pword" placeholder="Current Password" />
<input type="password" value="newpswd" class="form-control pword" placeholder="New Password" />
<input type="password" value="cnfrmpswd" class="form-control pword" placeholder="Confirm Password" />
<button class="btn btn-success btn-block" value="change">Submit</button>
</form>
This is my Controller code:
[HttpPost]
public ActionResult Change(FormCollection forms)
{
if (ModelState.IsValid)
{
string currentpswd=Convert.ToString(forms["currentpswd"]);
string newpass= (string)forms["newpswd"];
string confirmpass=forms["cnfrmpswd"];
Tbl_Users user = new Tbl_Users();
if (newpass == confirmpass)
{
user.UserPassword = newpass;
db.SaveChanges();
}
else
{
}
}
return RedirectToAction("Index", "ChangePassword");
}
How about using form collection You would create an action method that will handle the post when the user clicks the post button:
It will post a collect of the form fields to the controller, you can then reference by using the Name property from the original form fields.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(FormCollection forms)
{
var userPassword = (string)forms["UserPassword"];
var userSalt = (string)forms["UserSalt"];
}