How to assign value to input field? - c#

Im working on html content to disply data in mvc view binding data from model class, my requirement is to set values to input fields to html content from c#.
i want final content should come up with html content and values from model.
EXAMPLE:
<form action="/action_page.php">
<label for="fname">First name:</label>
<input type="text" id="fname" name="fname"><br><br>
<label for="lname">Last name:</label>
<input type="text" id="lname" name="lname"><br><br>
<input type="submit" value="Submit">
</form>
This is my html content which is coming from text file. i've data in my model, i.e,
public class EmployeeModel
{
public string fname { get; set; } = "Stack";
public string lname { get; set; } = "OverFlow";
}
In View :
#Html.Raw(ViewBag.htmlContent)

This is what the HtmlHelper class is for.
Set the view model in your view file and create a form around it.
#model Models.EmployeeModel
#using (Html.BeginForm("Edit", "Employees", FormMethod.Post))
{
#Html.LabelFor(m => m.fname)
#Html.TextBoxFor(m => m.fname)
<input type="submit" value="Submit"/>
}
Invoke the view from your controller with an instance of the model to edit.
public IActionResult Edit(int id)
{
...
employee = service.GetEmployeeById(id);
return View(employee);
}

one thig you could try would be to set values in Razor:
// your controller
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index()
{
return View(new EmployeeModel());// pass the actual viewmodel instance to the view here
}
}
#model EmployeeModel
.......
<form action="/action_page.php">
<label for="fname">First name:</label>
<input type="text" id="fname" name="fname" value="#Model.fname"><br><br> <!-- reference #Model fields as usual -->
<label for="lname">Last name:</label>
<input type="text" id="lname" name="lname" value="#Model.lname"><br><br><!-- reference #Model fields as usual -->
<input type="submit" value="Submit">
</form>
and a fiddle for you to play with: https://dotnetfiddle.net/37asAw

Related

Is there a way to access a complex model property of a page handler in the Razor page?

I have a page handler that has a complex property for model binding. I want to access the property to the razor page so I can use the tag helpers to generate the form inputs from the property.
This is my page handler:
public async Task<IActionResult> OnPostChangePassword(PasswordChangeInput Input)
{
// Some code
}
I want to access the property so I can use it with asp-for
#page
#model EditPasswordModel
#
{
//Some code
}
<form method="post">
<div class="flex justify-between my-1">
<label class="text-gray-700" for="cus_name">Password:</label>
<input asp-for="Input.Password" class="px-3 py-1 text-gray-900" />
</div>
<div class="flex justify-between my-1">
<label class="text-gray-700" for="cus_name">Confirm Password:</label>
<input asp-for="Input.ConfirmPassword" class="px-3 py-1 text-gray-900" />
</div>
<div>
<input type="submit" />
</div>
</form>
In your PageModel class you need to add a PasswordChangeInput property with [BindProperty] attribute.
public class EditPasswordModel : PageModel
{
[BindProperty]
public PasswordChangeInput Input { get; set; }
public async Task<IActionResult> OnPostChangePassword()
{
// Input property will be populated from form
}
}
And you also need to add asp-page-handler attribute to your form:
<form method="post" asp-page-handler="ChangePassword">
...
</form>
Edit:
If you don't want to add the property to the PageModel you can pass it as parameter to the OnPostChangePassword handler:
public class EditPasswordModel : PageModel
{
public async Task<IActionResult> OnPostChangePassword(PasswordChangeInput Input)
{
// Some code
}
}
BUT now you won't be able to use input tag helpers to create the form using asp-for="Input.Password". You must add the correct name attribute to the inputs manually:
<form method="post" asp-page-handler="ChangePassword">
<div class="flex justify-between my-1">
<label class="text-gray-700" for="cus_name">Password:</label>
<input name="Input.Password" class="px-3 py-1 text-gray-900" />
</div>
<div class="flex justify-between my-1">
<label class="text-gray-700" for="cus_name">Confirm Password:</label>
<input name="Input.ConfirmPassword" class="px-3 py-1 text-gray-900" />
</div>
<div>
<input type="submit" />
</div>
</form>
https://www.learnrazorpages.com/razor-pages/model-binding#binding-complex-objects

File not being passed from view to controller - ASP.NET Core

After clicking the submit button, the attachment list object is always null at the controller. Here's the code:
View model:
public class CreateTicketViewModel
{
...
public List<IFormFile> Attachments { get; set; }
}
View:
<form asp-action="CreateTicket">
...
<div class="form-group">
<label asp-for="Attachments" class="control-label">Attachments</label>
<input asp-for="Attachments" class="form-control" multiple />
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
Post method declaration:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> CreateTicket([FromForm]CreateTicketViewModel createTicketViewModel)
All in .NET 5
I got it to work.
The form tag has to have enctype attribute with a value of "multipart/formdata".

The view doesn't render when return View("viewname", model)

I'm developing asp.net core mvc web application. In my controller, there're two actions named 'Index' and 'Index2'.
When I submit form to 'Index2', it will return View("Index", model). But the view doesn't render correctly.
For example, if I input 'Steven' in the TextBox and submit to 'Index2' action, the Name property should be 'Name999'. The Textbox on the HTML should be show 'Name999', but actually, it still show 'Steven'.
The code sample:
#model WebApplication2.Controllers.Test
<form method="post" action="/home/Index2">
<div class="form-group">
<input type="text" asp-for="Name"/>
</div>
<div class="form-group">
<button type="submit">Add</button>
</div>
</form>
public IActionResult Index(Test test)
{
return View(test);
}
[HttpPost]
public IActionResult Index2(Test test)
{
test.Name = "Name999";
return View("Index",test);
}
public class Test
{
public string Name { get; set; }
}
you are submitting your form to index, not to index2
try this
view Index
#model WebApplication2.Controllers.Test
<form asp-action="Index2" method="post">
<div class="form-group">
<input type="text" asp-for="Name"/>
</div>
<div class="form-group">
<button type="submit">Add</button>
</div>
</form>
and try to refresh model state since you are doing a post back
ModelState.Clear();
test.Name = "Name999";
or change the view control
<input type="text" asp-for="Name" value="#Model.Name"/>
But when it is the same controller I am personaly usually using
return Index(test);
I can reproduce same issue, and I find that it seems to get value from ModelState prior to Model, which cause above issue.
To fix it, we can try to clear it, like below.
public IActionResult Index( )
{
return View();
}
[HttpPost]
public IActionResult Index2(Test test)
{
ModelState.Clear();
test.Name = "Name999";
return View("Index", test);
}
#model WebApplication99.Models.Test
<form method="post" action="/test/Index2">
<div class="form-group">
<input type="text" asp-for="Name" />
</div>
<div class="form-group">
<button type="submit">Add</button>
</div>
</form>
Note: the valus of ModelState
Result:

ASP.NET Core passing more than one parameters to view

In my project I would like to pass more than one parameter (id and description) to my view from the controller.
This is the structure of my project:
ProductController:
public IActionResult DettaglioDescrizione(int id, string descrizione)
{
ViewData["ProductId"] = id;
ViewData["ProductDescription"] = descrizione;
return View("Details");
}
Details.cshtml view:
<div class="text-center">
<h1 class="display-4">Prodotti</h1>
<p>Id prodotto: #ViewData["ProductId"]</p>
<p>Descrizione prodotto: #ViewData["ProductDescription"]</p>
</div>
I know that I have to modify my pattern in Startup.cs. If I modify in this way it works properly:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}/{descrizione?}");
});
My question is: there is a better way to do this without add "/" for each parameter?
There are three binding sources in model binding
Form Values
Route Values
Query string
what you are doing right now is from a route value, maybe you can use a query string /1?description=value or maybe you can do httppost and get the value from the form.
If you want to pass multiple parameters from controller to action or from action to controller.You can try to create a Model.Action can pass data with a form to controller.Action returns a model to view.So that you don't need to pass more than one parameters with route or ViewData.Here is a demo:
Model:
public class Product
{
public int ProductId { get; set; }
public string descrizione { get; set; }
}
Action:
public IActionResult DettaglioDescrizione(Product product)
{
return View("Details",product);
}
Details View:
#model Product
<div class="text-center">
<h1 class="display-4">Prodotti</h1>
<p>Id prodotto: #Model.ProductId</p>
<p>Descrizione prodotto: #Model.ProductDescription</p>
</div>
View:
#model Product
<form method="post" asp-action="DettaglioDescrizione">
<div class="form-group">
<label asp-for="ProductId" class="control-label"></label>
<input asp-for="ProductId" class="form-control" />
</div>
<div class="form-group">
<label asp-for="ProductDescription" class="control-label"></label>
<input asp-for="ProductDescription" class="form-control" />
</div>
<input type="submit" value="submit" />
</form>
result:

Why do my tag helpers not work in MVC?

I have a form with 3 inputs using tag helpers and a data transfer object with these 3 properties.
When I add the object to my database the values are empty. I set the properties to [Required] and even this doesn't give me an error.
I declared this as model in the form cshtml file:
#model CRM_Collect.Dtos.ClientDto
Form:
<form asp-controller="Client" asp-action="AddClient" method="post">
<div class="form-group">
<label for="companyName">Company</label>
<input asp-for="Company" class="form-control" id="companyName" placeholder="Company name">
</div>
<div class="form-group">
<label for="comment">Comment</label>
<textarea asp-for="Comment" class="form-control" id="comment" rows="3"></textarea>
</div>
<div class="form-group">
<label for="companyWebsite">Website</label>
<input asp-for="Website" class="form-control" id="companyWebsite" placeholder="www.example.com">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
Data transfer class
[Required]
public String Company { get; set; }
[Required]
public String Website { get; set; }
[Required]
public String Comment { get; set; }
Post controller
[HttpPost]
public ActionResult AddClient(ClientDto client)
{
ClientContext clientContext = new ClientContext();
Client clientToAdd = new Client { Comment = client.Comment, Company = client.Company, Website = client.Website };
clientContext.Clients.Add(clientToAdd);
clientContext.SaveChanges();
return View();
}
Explicitly use the FromBody attribute on the action's parameter. Also consider check ing model state as the model is using [Required] validation attribute.
[HttpPost]
public ActionResult AddClient([FromBody]ClientDto client) {
if(ModelState.IsValid) {
using(var clientContext = new ClientContext()) {
var clientToAdd = new Client {
Comment = client.Comment,
Company = client.Company,
Website = client.Website
};
clientContext.Clients.Add(clientToAdd);
clientContext.SaveChanges();
}
}
return View();
}
Turns out I am using a version that doesn't support the helper tags. I am not using ASP.NET Core which is the issue.
This is the most common mistake I have seen when people try to post a form to a controller. You need to have the name attribute set on all your inputs of the form so the controller will process the data inside of the input field and correspond that to the properties of the model serving as the parameter of your action.
Your form should look like this:
<form asp-controller="Client" asp-action="AddClient" method="post">
<div class="form-group">
<label for="companyName">Company</label>
<input asp-for="Company" name="company" class="form-control" id="companyName" placeholder="Company name">
</div>
<div class="form-group">
<label for="comment">Comment</label>
<textarea asp-for="Comment" name="comment" class="form-control" id="comment" rows="3"></textarea>
</div>
<div class="form-group">
<label for="companyWebsite">Website</label>
<input asp-for="Website" name="website" class="form-control" id="companyWebsite" placeholder="www.example.com">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>

Categories