How to get data from multiple elements - asp.net

i have next ViewModel:
public class ChatCreationViewModel
{
public string ChatName { get; set; }
public List<User> Friends { get; set; }
public List<(string, bool)> Partcipants { get; set; }
}
and next view:
#model GalkaNet.ViewModels.ChatCreationViewModel
<form method="post" asp-action="NewChat" asp-controller="Chat" enctype="multipart/form-data">
<h2>Создание беседы</h2>
<label>Chat name: </label> <input type="text" name="ChatName" placeholder="Name" value=""></p>
<p><input type="submit" value="Create" /></p>
#for(int i = 0; i < Model.Friends.Count; i++)
{
<div>
<label>#Model.Friends[i].NickName</label>
<p> #Html.EditorFor(Model => Model.Partcipants[i].Item2)</p>
</div>
}
</form>
</div>
The thing is: i want to create a list of elements with user names and checkboxes. Once the form is submitted i want to place values from each checkbox combined with id of user (in front of whose name this checbox was) into Partcipants list of my view model that is going to server. How should i do this?

Create a Model Like this
public string ChatName { get; set; }
public List<UserModel > Friends { get; set; }
Your User Model Properties(ID,UserName,isSelected)
Fill these properties from your db
Id = friend.Id;
UserName = friend.Name,
isSelected = false
Your View
#for (int i = 0; i < Model.Friends.Count; i++)
{
<div class="form-check m-1">
<input type="hidden" asp-for="#Model.Friend[i].Id " />
<input type="hidden" asp-for="#Model.Friend[i].Username" />
<input asp-for="#Model.Friend[i].isSelected" class="form-check-
input" />
<label class="form-check-label" asp-
for="#Model.Friend[i].isSelected">
#Model.Friend[i].Username </label>
</div>
}

Related

How to reuse a form in asp.net core MVC?

I've got number of places where I need to use an address in my app so I tried to make this DRY and create an address partial view like this:
#model AddressEditViewModel
<div class="mb-3">
<label asp-for="Address1" class="form-label"></label>
<input asp-for="Address1" class="form-control" />
<span asp-validation-for="Address1" class="text-danger"></span>
</div>
<div class="mb-3">
<label asp-for="Address2" class="form-label"></label>
<input asp-for="Address2" class="form-control" />
<span asp-validation-for="Address2" class="text-danger"></span>
</div>
<div class="mb-3">
<label asp-for="City" class="form-label"></label>
<input asp-for="City" class="form-control" />
<span asp-validation-for="City" class="text-danger"></span>
</div>
<div class="row mb-3">
<div class="col-md">
<label asp-for="USStateID" class="form-label"></label>
<select asp-items="#Model.USStates" asp-for="USStateID" class="form-select"></select>
<span asp-validation-for="USStateID" class="text-danger"></span>
</div>
<div class="col-md">
<label asp-for="Zip" class="form-label"></label>
<input asp-for="Zip" class="form-control" />
<span asp-validation-for="Zip" class="text-danger"></span>
</div>
</div>
But I had no luck when I put it into another page with the partial tag helper:
<partial name="_Address" model="Model.Address" />
Now I understand why this technique doesn't work - that partial views are just for making HTML and don't get processed by the model binder on the way back.
But I would prefer not to copy and paste forms all over my site. Is there any better way to reuse commonly used form bits like this?
You can use this method.
#await Html.PartialAsync("_PartialName", customViewData)
You can find more details in here.
https://learn.microsoft.com/en-us/aspnet/core/mvc/views/partial?view=aspnetcore-7.0#access-data-from-partial-views
You need to make sure the type of Model.Address is AddressEditViewModel.And make sure the partial view is in the right folder so that you can call it.
Model:
public class TestModel {
public AddressEditViewModel Address { get; set; }
}
public class AddressEditViewModel {
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public int USStateID { get; set; }
public List<SelectListItem> USStates { get; set; }
public string Zip { get; set; }
}
Action:
public IActionResult B()
{
return View(new TestModel {Address=new AddressEditViewModel { Address1="d1",Address2="d2", City="C", USStates=new List<Microsoft.AspNetCore.Mvc.Rendering.SelectListItem> { }, Zip="111"} });
}
_Address.cshtml path:
Views/Shared/_Address.cshtml
B.cshtml:
#model TestModel
<partial name="_Address" model="Model.Address" />
result:

ASP.NET Transferring data to postgresql

I can't understand why the data is not transferred to the database
There is a controller
public class PeopleController : Controller
{
private readonly string ConnectionString = "Host=localhost;Port=5432;Database=CrudDb;Username=postgres;Password=12345;Maximum Pool Size=100";
[HttpGet]
public IActionResult Create()
{
return View();
}
[HttpPost]
public IActionResult Create(People people)
{
if (ModelState.IsValid)
{
IDbConnection con;
string insertQuery = "INSERT INTO people(name, phone) VALUES(#Name, #Phone)";
con = new NpgsqlConnection(ConnectionString);
con.Open();
con.Execute(insertQuery, people);
con.Close();
return RedirectToAction(nameof(Index));
}
return View(people);
}
}
There is a model for her
public class People
{
public int Id { get; set; }
public string Name { get; set; }
public int Phone { get; set; }
}
And there is a page
<form asp-action="Contacts">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Name" class="col-form-label">Имя</label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Phone" class="col-form-label">Телефон </label>
<input asp-for="Phone" class="form-control" />
<span asp-validation-for="Phone" class="text-danger"></span>
</div>
<div class="form-group p-4">
<input type="submit" value="Создать" class="btn btn-outline-success btn-sm" />  
</div>
</form>
It does not issue any errors, I enter data on the page, but this data is not transmitted to the database. From libraries, Dapper and Npgsql are connected

ASP.net : How to pass a null object, instead of an empty one?

How can one have a null object, instead of an empty objet (all properties to null) ? More specifically when the given object's name is not in the form.
Here is my example. I'm posting a simple form to my controller. I have some data bound to p_user, and p_password, but not to p_info. I would have expected it to be null.
Note : All the objects are Entities obtained using a DbFirst Approach with EntityFramework.
Instead, I have the following :
Form :
<form id="accountForm" method="post" action="#Url.Action("CreateAccount")">
<div class="form-group">
<label for="email">EMail</label>
<input id="email" class="form-control" type="email" name="p_user.email" aria-describedby="emailHelp" placeholder="Enter your email address" />
</div>
<div class="form-group">
<label for="username">Username</label>
<input id="username" name="p_user.username" class="form-control " type="text" aria-describedby="usernameHelp" placeholder="Enter your username" />
<small id="usernameHelp" class="form-text text-muted"></small>
</div>
<div class="form-group">
<label for="password">Password</label>
<input id="password" name="p_password" class="form-control" type="password" placeholder="Enter your password">
</div>
<button type="submit" class="btn btn-primary">Créer</button>
</form>
Controller :
public ActionResult CreateAccount(T_User p_user, string p_password, T_UserInfo p_info = null)
T_UserInfo :
public partial class T_UserInfo
{
public int id_user { get; set; }
public string forname { get; set; }
public string lastname { get; set; }
public string avatar_path { get; set; }
public virtual T_User T_User { get; set; }
}

How to build object within a form in razor view

public class MyModel
{
public int Id { get; set; }
public string Name { get; set; }
public MyType MyType { get; set; }
public IMyConfig MyConfig { get; set; }
}
public enum MyType
{
FirstConfig,
SecondConfig,
ThirdConfig
}
public interface IMyConfig
{
string BuildFirstJson();
string BuildSecondJson();
}
public class FirstConfig : IMyConfig
{
public string cat { get; set; }
public string dog { get; set; }
public string lion { get; set; }
public string BuildFirstJson()
{
...
}
public string BuildSecondJson()
{
...
}
}
public class SecondConfig : IMyConfig
{
public string bear { get; set; }
public int pig { get; set; }
public string fish { get; set; }
public string shark { get; set; }
public string dolphin { get; set; }
public string BuildFirstJson()
{
...
}
public string BuildSecondJson()
{
...
}
}
//ThirdConfig built similarly
So what I am trying to do is build a form in a razor view that can handle the MyModel class and switches the displayed IMyConfig bindings based on the selected MyType for example, if FirstConfig is selected from the enum list, then FirstProp, SecondProp, ThirdProp text boxes are displayed and when the form is submitted, those properties are correctly built into a FirstConfig object and passed into MyModel as a IMyConfig interface. I have no idea how to accomplish this part, I am plan on using jquery .change() to listen for a switch in the MyType dropdown. But I am not sure how to handle the seperate displaying and automatic model building(if that makes sense).
If that doesn't make sense, the quick version is I am trying to build a razor view form for MyModel and don't how to approach the MyConfig property which is based on the MyType property.
<form asp-action="ActivityCreateSubmit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Id" class="control-label"></label>
<input asp-for="Id" class="form-control" />
<span asp-validation-for="Id" class="text-danger"></span>
</div>
<div class="form-group" style="display: none;">
<label asp-for="Name" class="control-label"></label>
<input asp-for="Name" class="form-control" value="#ViewBag.AppId" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="MyType" class="control-label"></label>
<select id="selection" asp-for="MyType" asp-items="Html.GetEnumSelectList<MyType>()">
<option value="">Select...</option>
</select>
<span asp-validation-for="MyType" class="text-danger"></span>
</div>
#switch(Model.MyType)
{
case FirstConfig:
<input name="first-input" />
<input name="second-input" />
<input name="third-input" />
break;
case SecondConfig:
... Do something ...
break;
}
<div class="form-group">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</form>
Controller -
//Ignore ActivityTable, it is a dependency injection.
public ActionResult ActivityCreateSubmit(ActivityTable at, MyModel a)
{
at.AddActivity(a)
return View("../Home/Index");
}
//This is the page I am working on creating
public ActionResult ActivityCreate()
{
return (View());
}
I could not get exactly what your problem is, but I guess you need the following (I am glad to edit the answer if that is not what you need).
you can check the selected value in that enum inside your Razor page:
<form>
#switch(Model.MyType)
{
case FirstConfig:
<input name="cat"/>
<input name="dog" />
<input name="lion" />
break;
case SecondConfig:
... Do something ...
break;
}
</form>
UPDATE:
The action ActivityCreateSubmit should have a parameter of some class type the class you require (FirstConfig). The name you gave to each input MUST be identical to the properties in your class FirstConfig, i.e., like this:
<input name="cat"/>
<input name="dog"/>
<input name="lion"/>
Now try to submit, it should work.

How to post a list from view to controller mapped to viewModel in Asp.net core?

Here is my ViewModel
public class VideoViewModel
{
public string Movie { get; set; }
public int Order { get; set; }
public IList<VideoContent> VideoContents { get; set; }
}
How can I pass data from fields in view to controller mapped to my collection in my viewModel?
This code in my view is passing Movie and Order to controller but I can't figure out hos to send the collection too.
#model ViewModels.VideoViewModel
<form method="post">
<div class="form-group">
<label for="movie">Movie</label>
<input type="text" name="Movie" id="movie" class="form-control">
</div>
<div class="form-group">
<label for="order">Order</label>
<input type="text" name="Order" id="order" class="form-control">
</div>
<button type="submit" class="btn btn-primary">Add to database</button>
</form>
Thanks in advance!
/ Kalle
ASP .NET Core uses the name attribute to bind the data from the input fields to the view model.
This should work for passing the collection.
for(int c = 0; c < VideoContents.Count; c++)
{
<input name="VideoContents[#c].FirstProperty" value="#Model.VideoContents[#c].FirstProperty"/>
<input name="VideoContents[#c].SecondProperty" value="#Model.VideoContents[c].SecondProperty"/>
}

Resources