Using MVC4 am wanting to implement functionality which will allow a user to add new items to the database.
I've managed to achieve this adding items to a single table, but now I need to display data from multiple tables, then populate the added / selected data to those tables.
I have these 3 tables
Threats
ID
Description
ThreatHasSecurityEvent
ThreatID
SecurityEventID
SecrutiyEvents
ID
Description
And here's my code so far:
ViewModel
public class ThreatWithSecurityEvents
{
public Threat Threat { get; set; }
public SecurityEvent SecurityEvent { get; set; }
public List<int> SecurityEventIds { get; set; }
public ThreatWithSecurityEvents()
{
SecurityEventIds = new List<int>();
}
}
Get Controller
[HttpGet]
public ActionResult AddNewThreat()
{
ThreatWithSecurityEvents ViewModel = new ThreatWithSecurityEvents();
var SecurityEvents = _DBContext.SecurityEvents.Select(x => new SelectListItem()
{
Text = x.Description,
Value = x.ID.ToString()
});
ViewBag.SecurityEventDropdown = SecurityEvents;
return View(ViewModel);
}
View
#model RiskAssesmentApplication.Models.ThreatWithSecurityEvents
#{
ViewBag.Title = "AddNewThreat";
//Layout = "~/Views/Shared/MasterLayout.cshtml";
}
<div style="font-family: Calibri">
<h2>AddNewThreat</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Threat</legend>
#using (Html.BeginForm("Add New Threat", "Threats"))
{
Html.HiddenFor(model => model.SecurityEventIds);
<div class="editor-label">
#Html.LabelFor(model => #Model.Threat.Description, "Threat Description")
</div>
<div class="editor-field">
#Html.EditorFor(model => #Model.Threat.Description)
#Html.ValidationMessageFor(model => #Model.Threat.Description)
</div>
<div class="editor-label">
#Html.LabelFor(model => #Model.SecurityEvent.Description, "Associated Security Event")
</div>
<div class="editor-field">
#Html.DropDownListFor(x => x.SecurityEventIds, ViewBag.SecurityEventDropdown as IEnumerable<SelectListItem>)
</div>
<p>
<input type="submit" value="Add New" />
</p>
}
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
</div>
Am unsure how to implement the Post Action Method and a Save Method in the repository.
Previously I could inject a new Threat Object and send it to the edit view doing something like:
Previous Get Method - AddNewThreat
[HttpGet]
public ActionResult AddNewThreat()
{
return View("EditThreat", new Threat());
}
and I would then use the EditThreat Action Method to post back
Previous Post Action - AddNewThreat
[HttpPost]
public ActionResult EditThreat(Threat Threat)
{
if (ModelState.IsValid)
{
repository.SaveThreat(Threat);
TempData["message"] = string.Format("{0} new description has been saved", Threat.Description);
return RedirectToAction("GetThreat", new { ThreatID = Threat.ID });
}
else
{
// something is incorrect!
return View(Threat);
}
}
Previous Save Method - SaveThreat From Repository
public void SaveThreat(Threat Threat)
{
if (Threat.ID == 0)
{
_context.Threats.Add(Threat);
}
else
{
Threat dbEntry = _context.Threats.Find(Threat.ID);
if (dbEntry != null)
{
dbEntry.Description = Threat.Description;
}
}
_context.SaveChanges();
}
That's as far as I have got so far.
I want the user to be able to enter a new threat description and then select a security event or multiple events from a drop down list which will be associated with the new threat.
I realize am going to have to change the post back action method in the controller and the Save method in my repository, but I cant work out how to get both the new Threat description and the existing security events saved back to the database. I've had a search but as of yet haven't found / understood anything.
Any advice/help would be great.
Thanks
You view model should be
public class NewThreatVM
{
public string Description { get; set; } // add validation attributes as required
public List<int> SelectedSecurityEvents { get; set; }
public SelectList SecurityEventList { get; set; } // or IEnumerable<SelectListItem>
}
Side note: The Threat.ID property is not required in a create view, however if your want to use this for editing an existing Threat as well, add property int? ID and use if (model.ID.HasValue) in the POST method to determine if its a new or existing Threat
and the simplified view
#model yourAssembly.NewThreatVM
#Html.BeginForm())
{
#Html.TextBoxFor(m => m.Description)
#Html.ListBoxFor(m => m.SelectedSecurityEvents, Model.SecurityEventList)
<input type="Submit" value="Create" />
}
Side notes: Your view should not include a hidden input for the Security Event ID's (you cannot bind an input to a complex object or collection)
then the controller
public ActionResult Create()
{
NewThreatVM model = new NewThreatVM model();
ConfigureViewModel(model);
return View(model);
}
[HttpPost]
public ActionResult Create(NewThreatVM model)
{
if (!ModelState.IsValid)
{
ConfigureViewModel(model);
return View(model);
}
// Initialize new data model and map properties from view model
Threat threat = new Threat() { Description = model.Description };
// Save it (which will set its ID property)
_context.Threats.Add(Threat);
_context.SaveChanges();
// Save each selected security event
foreach (int selectedEvent in model.SelectedSecurityEvents)
{
ThreatHasSecurityEvent securityEvent = new ThreatHasSecurityEvent()
{
ThreatID = threat.ID,
SecurityEventID = selectedEvent
};
_context.ThreatHasSecurityEvents.Add(securityEvent);
}
_context.SaveChanges();
return RedirectToAction("GetThreat", new { ThreatID = threat.ID });
}
private void ConfigureViewModel(NewThreatVM model)
{
var securityEvents = _context.SecurityEvents;
model.SecurityEventList = new SelectList(securityEvents, "ID", "Description");
}
I believe the easiest way to achieve this, is "dividing" your form into separated steps.
You have2 entities: Threats, SecurityEventID
Threat has a collection of SecurityEvents
Create a form to add/edit Threats (url: Threats/Add | Threats/Edit/ThreatId)
Create a form to add/delete Events of an existing Threat (url: Threats/AddEvent/ThreatIdHere
Use custom ViewModels instead of the original class to send data to controller. Examples:
public class AddThreatViewModel
{
public string Description { get; set; }
//since it's a add view model, we dont need a ThreatId here
}
[HttpPost]
public ActionResult AddThreat(AddThreatViewModel model)
{
//convert the view model to Threat, add to database
}
public class AddThreatEvent
{
public int ThreatId { get; set; }
public int SecrutiyEventId { get; set; }
}
[HttpPost]
public ActionResult AddThreatEvent(AddThreatEventmodel)
{
//add threat event into existing threat
}
Related
Not understanding what I am overseeing here ...
I have a Model which I render in a View.
This is the SubscriptionViewModel:
public Subscription Subscription { get; set; }
public DayOfWeek DayOfWeek { get; set; }
public List<DateTime> SomeDates { get; set; }
In the View I have populated a table with data from the SubscriptionViewModel.
In each table row there is an If/else statement, where in each part I placed a Form so that the data can be posted back to the SubscriptionController, this is a pseudo example:
if (condition)
{
using (Html.BeginForm("Subscribe", "Subscription", FormMethod.Post))
{
#Html.ActionLink("text", "Subscribe", new { #date = item }, new { #class = "btn btn-warning btn-radius" })
}
}
else
{
using (Html.BeginForm("UnSubscribe", "Subscription", FormMethod.Post))
{
#Html.ActionLink("text", "UnSubscribe", new { #date = item }, new { #class = "btn btn-danger btn-radius" })
}
}
This is the SubscriptionContoller method being triggered:
[AllowAnonymous]
public ActionResult Subscribe(SubscriptionViewModel model, string date)
{
return View();
}
The POST is triggered and my Model is not NULL, the date parameter also has the correct value, the only thing which is lost is the parameters from Subscription Entity from my SubscriptionViewModel. They are not NULL but they just don't have their initial values when coming to the View initially...
No clue what I am overseeing, I tried using TempData.Keep() into the View (which I never needed to do before) but that doesn't work either.
Any suggestion is welcome!
Thank you!
This answer assumes you don't want the values for the Subscription to come from the form but rather stay as they were when the values are originally sent to the view which sounds like what you are after.
You need to include the values for the subscription in the form using hidden fields (see example 1). Alternatively you will need to populate the subscription in your post method in the same way that it is in your get method (see example 2).
Here are 2 simple examples demonstrating what I mean
Suppose this is your subscription class
public class Subscription
{
public int Id { get; set; }
public string Name { get; set; }
}
Example 1
The HiddenField way
The controller
public class SubscriptionController : Controller
{
[AllowAnonymous]
public ActionResult Subscribe()
{
var viewModel = new SubscriptionViewModel
{
Subscription = GetSubscription()
};
return View(viewModel);
}
[AllowAnonymous]
[HttpPost]
public ActionResult Subscribe(SubscriptionViewModel model, string date)
{
return View();
}
private Subscription GetSubscription()
{
return new Subscription
{
Id = 1,
Name = "My Subscription"
};
}
}
The view
#model {The namespace}.SubscriptionViewModel
#using (Html.BeginForm("Subscribe", "Subscription", FormMethod.Post))
{
//Other fields
#Html.HiddenFor(x => x.Subscription.Id)
#Html.HiddenFor(x => x.Subscription.Name)
<input type="submit" value="submit" />
}
Example 2
The get back in the controller way
The controller
public class SubscriptionController : Controller
{
[AllowAnonymous]
public ActionResult Subscribe()
{
var viewModel = new SubscriptionViewModel
{
Subscription = GetSubscription()
};
return View(viewModel);
}
[AllowAnonymous]
[HttpPost]
public ActionResult Subscribe(SubscriptionViewModel model, string date)
{
model.Subscription = GetSubscription();
return View();
}
private Subscription GetSubscription()
{
return new Subscription
{
Id = 1,
Name = "My Subscription"
};
}
}
The view
#model {The namespace}.SubscriptionViewModel
#using (Html.BeginForm("Subscribe", "Subscription", FormMethod.Post))
{
//Other fields
<input type="submit" value="submit" />
}
I have a simple mvc5 code first application, It has a ms SQL database in the back-end and and a form in the front-end.
While I insert into database via the front end form, it does not generate any error, everything seems OK but when i check the back end database table, then all values in the newly inserted row are showing as NULL.
This is my code for model:
public class students
{
public int Id { get; set; }
[Display(Name = "Name")]
public string st_name { get; set; }
[Display(Name = "Father's Name")]
public string st_father_name { get; set; }
public string st_contact { get; set; }
}
This is the View Model class:
public class AddStudentViewModel
{
public students stdntss { get; set; }
}
This is the controller:
public ActionResult Index()
{
var std = _context.stdnts;
if (std==null)
{
return Content("Nothing Found");
}
return View(std);
}
public ActionResult AddStudent()
{
return View();
}
[HttpPost]
public ActionResult Insert(students st)
{
_context.stdnts.Add(st);
_context.SaveChanges();
return RedirectToAction("Index","Students");
}
And finally this is the view:
#model school2.ViewModels.AddStudentViewModel
#{
ViewBag.Title = "AddStudent";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>New student's registration form</h2>
#using (Html.BeginForm("Insert","Students"))
{
<div class="form-group">
#Html.LabelFor(m=> m.stdntss.st_name)
#Html.TextBoxFor(m=> m.stdntss.st_name, new { #class="form-control"})
</div>
<div class="form-group">
#Html.LabelFor(m => m.stdntss.st_father_name)
#Html.TextBoxFor(m => m.stdntss.st_father_name, new { #class = "form-control" })
</div>
<div class="form-group">
#Html.LabelFor(m => m.stdntss.st_contact)
#Html.TextBoxFor(m => m.stdntss.st_contact, new { #class = "form-control" })
</div>
<button type="submit" class="btn btn-primary">Save</button>
}
Kindly assist me if anyone has any clue?
One way to solve this is to change the POST method to accept the same model as the view.
try changing
public ActionResult Insert(students st)
{
_context.stdnts.Add(st);
_context.SaveChanges();
return RedirectToAction("Index","Students");
}
to
public ActionResult Insert(AddStudentViewModel st)
{
_context.stdnts.Add(st.stdntss );
_context.SaveChanges();
return RedirectToAction("Index","Students");
}
or changing the model of the form to simply be student.
I think that change #Html.TextBoxFor(model=> model.stdntss.st_name, new { #class="form-control"}). because call Model, #model school2.ViewModels.AddStudentViewModel . Variable default Model.
I am a new to MVC and still learning! I am trying to create a very basic App in my web which allows users to convert money value according to their preference. I made the web APi and was successful to call the service to my forms. However, in my controller I managed to get the currencies (names) to the index view, but cannot post the form back once entering a value in the text box to generate the partial view! What am I doing wrong in my codes?!
Currency Controller
namespace MVC_ATM.Controllers
{
public class CurrencyController : Controller
{
[HttpGet]
// GET: Currency
public ActionResult Index()
{
CurrenciesClient Cur = new CurrenciesClient();
var listCurrency = Cur.findAll();
SelectList list = new SelectList(listCurrency,"Id", "CurrencyName");
ViewBag.listCurrencies = list;
return View();
}
[HttpPost]
public ActionResult Index(Currencies cur)
{
if (!ModelState.IsValid)
{
string errors = string.Join("<br />", ModelState.Values
.SelectMany(x => x.Errors)
.Select(x => x.ErrorMessage));
return new ContentResult { Content = errors };
var rate = Convert.ToDecimal(cur.ConversionRate);
if (cur.CurrencyName == cur.CurrencyName)
{
ModelState.AddModelError("CurrencyCountry", "Can't make the conversion for the same value");
}
else if (cur.CurrencyName != cur.CurrencyName)
{
foreach (var currency in cur.CurrencyName)
{
ViewBag.Theresult = rate * cur.Value;
}
return PartialView("_CurrencyValue");
}
}
return View();
}
}
}
Currencies Model
namespace Project.Model
{
public class Currencies
{
public int Id { get; set; }
public string CurrencyName { get; set; }
public string CurrencyCountry {get; set;}
public decimal Value { get; set; }
public string ConversionRate { get; set; }
}
}
Index View
#model Project.Model.Currencies
#{
ViewBag.Title = "Index";
}
<h2>Currency</h2>
<body>
<div class="converter">
Convert: #Html.TextBoxFor(m => m.ConversionRate, new { #size = "5" })
<div class="form-group">
#Html.Label("Convert from", new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.DropDownList("Currency List", ViewBag.listCurrencies as SelectList, "Please Select a currency")
</div>
</div>
<div class="form-group">
#Html.Label("Convert to", new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.DropDownList("Currency List", ViewBag.listCurrencies as SelectList, "Please Select a currency")
</div>
</div>
<div>
<button type="submit" class="btn btn-primary">Convert</button>
</div>
</div>
</body>
Couple of things to notice, is the POST action and missing form tag in the view . You created a POST action that accepts Currencies model but the form doesn't post that. Only ConversionRate will bind to the model. To get the "Currency From" and "Currency To" and the "Conversion Rate" you will require a different approach/small changes.
ConversionModel.cs a new Model for index page that will capture your required fields.
public class ConversionModel
{
[Required]//decimal would be better but up to you requirement
public decimal ConversionRate { get; set; }
[Required]
public int FromCurrencyId {get;set;}
public SelectList FromCurrencies {get;set;}
[Required]
public int ToCurrencyId {get;set;}
public SelectList ToCurrencies {get;set;}
}
Get: while there is nothing wrong with what you've done, lets use a model approach and tightly bind it.
public ActionResult Index()
{
CurrenciesClient Cur = new CurrenciesClient();
var listCurrency = Cur.findAll();
ConversionModel model = new ConversionModel();
model.FromCurrencies = new SelectList(listCurrency,"Id", "CurrencyName");
model.ToCurrencies = new SelectList(listCurrency,"Id", "CurrencyName");
return View(model);
}
Post: Important thing here to notice is the SelectList will not be posted back. Only the ConversionRate, FromCurrencyId and ToCurrencyId are sent back not the Lists. If error occurs you will need to rebuild the lists and send it back in the model.
[HttpPost]
public ActionResult Index(ConversionModel curModel)
{
if(ModelState.IsValid)
{
if(curModel.FromCurrencyId ==curModel.ToCurrencyId)
{
//do something if same currecnies and return.
}
else
{
//Get the currencyList with rates from db
//use currency ToCurrencyId and FromCurrencyId to fetch the 2 currencies
// perform conversion with curModel.ConversionRate with existing logic
}
}
//Don'f forget to rebuild the Select Lists...
return View(curModel);
}
View:
#model Project.Model.ConversionModel
#{
ViewBag.Title = "Index";
}
#using (Html.BeginForm("Index", "Currency", FormMethod.Post)
{
#Html.TextBoxFor(m => m.ConversionRate, new { #size = "5" })
#* Please check the syntax *#
#Html.DropDownListFor(m => m.FromCurrencyId , Model.FromCurrencies as SelectList)
#Html.DropDownListFor(m => m.ToCurrencyId , Model.ToCurrencies as SelectList)
<button type="submit" class="btn btn-primary">Convert</button>
}
Not a CUT_COPY_PASTE. please do check for errors if any. It is only an approach.
ajax POST probably the next thing to learn... Let us know.
You need to put your items inside a form like this:
#using (Html.BeginForm("Index", "Currency", FormMethod.Post)
{
// Your form items
}
How can I create a view that has multiple models that need validation and also has multiple forms to submit all within the same view?
I have the solution below. As I was typing it up I was able to figure it out, so hopefully it will help someone else. If others have a better approach or comments, please feel free to post!
I have a view that contains a ViewModel, which combines 2 models. Here is the ViewModel, along with the other classes:
public class PlayerFormViewModel
{
public PlayerFormEnglish PlayerFormEnglish { get; set; }
public PlayerFormSpanish PlayerFormSpanish { get; set; }
}
public class PlayerFormEnglish : PlayerFormInformation { }
public class PlayerFormSpanish : PlayerFormInformation { }
public class PlayerFormInformation
{
[Required(ErrorMessage = "First name is a required field.")]
[Display(Name = "First name")]
public string FirstName { get; set; }
// Used as a dropdown in the view
[Display(Name = "Gender")]
public IEnumerable<SelectListItem> Gender{ get; set; }
}
My main view contains the ViewModel and 2 forms:
#model Namespace.Models.PlayerFormViewModel
#using (Html.BeginForm("PlayerTest", "Profile"))
{
#Html.AntiForgeryToken()
<h3>English</h3>
#Html.LabelFor(m => m.PlayerFormEnglish.FirstName)
#Html.TextBoxFor(m => m.PlayerFormEnglish.FirstName)
#Html.ValidationMessageFor(m => m.PlayerFormEnglish.FirstName)
#Html.LabelFor(m => m.PlayerFormEnglish.Gender)
#Html.DropDownListFor(m => m.PlayerFormEnglish.Gender, new SelectList(Model.PlayerFormEnglish.Gender, "Value", "Text"))
<button type="submit" class="btn btn-default" name="ButtonType" value="SaveEnglishForm">Save</button>
}
#using (Html.BeginForm("PlayerTest", "Profile"))
{
#Html.AntiForgeryToken()
<h3>Spanish</h3>
#Html.LabelFor(m => m.PlayerFormSpanish.FirstName)
#Html.TextBoxFor(m => m.PlayerFormSpanish.FirstName)
#Html.ValidationMessageFor(m => m.PlayerFormSpanish.FirstName)
#Html.LabelFor(m => m.PlayerFormSpanish.Gender)
#Html.DropDownListFor(m => m.PlayerFormSpanish.Gender, new SelectList(Model.PlayerFormEnglish.Gender, "Value", "Text"))
<button type="submit" class="btn btn-default" name="ButtonType" value="SaveSpanishForm">Save</button>
}
When the page first loads, I pre-populate the fields like this:
[HttpGet]
public ActionResult PlayerTest()
{
PlayerFormViewModel model = new PlayerFormViewModel();
model.PlayerFormEnglish = new PlayerFormEnglish();
model.PlayerFormSpanish = new PlayerFormSpanish();
model.PlayerFormEnglish.FirstName = "Brad";
List<SomeObject> genderList = GetDataForDropdown();
model.PlayerFormEnglish.Gender = ConvertData(genderList);
model.PlayerFormSpanish.Gender = ConvertData(genderList);
return View(model);
}
Finally, I validate and update the saved form when a user clicks the save button:
[HttpPost]
[ValidateInput(false)]
[ValidateAntiForgeryToken]
public ActionResult PlayerTest(PlayerFormViewModel model, string ButtonType)
{
if (ButtonType.Equals("SaveEnglishForm"))
{
if (ModelState.IsValid)
{
return RedirectToAction("SuccessfulSave", "Profile");
}
model.PlayerFormSpanish = new PlayerFormSpanish();
}
else
{
if (ModelState.IsValid)
{
return RedirectToAction("SuccessfulSave", "Profile");
}
model.PlayerFormEnglish = new PlayerFormEnglish();
}
// I can repopulate the fields here just as before
model.PlayerFormEnglish.FirstName = "Brad";
List<SomeObject> genderList = GetDataForDropdown();
model.PlayerFormEnglish.Gender = ConvertData(genderList);
model.PlayerFormSpanish.Gender = ConvertData(genderList);
// Return model which will mark the required fields in the UI
return View(model);
}
Hope this helps!
I'm trying to create HttpPost method to create a new database entry. It should take 2 foreign IDs from different database tables and "name". Here's the model:
public class Domena
{
public int DomenaID { get; set; } // this domains ID
public int TLDID { get; set; } // foreign id
public int KlientID { get; set; } // foreign id
public string Nazwa { get; set; }
public virtual TLD TLD { get; set; }
public virtual Klient Klient { get; set; }
}
Right, so basically this is what I have now :
// GET: /Domena/Add_Domain
public ActionResult Add_Domain()
{
ViewBag.TLDID = new SelectList(db.TLDs, "TLDID", "Typ");
ViewBag.KlientID = new SelectList(db.Klienci, "KlientID", "KlientID");
return View();
}
//
// POST: /Domena/Add_Domain
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Add_Domain(Domena domena)
{
if (ModelState.IsValid)
{
db.Domeny.Add(domena);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.TLDID = new SelectList(db.TLDs, "TLDID", "Typ", domena.TLDID);
ViewBag.KlientID = new SelectList(db.Klienci, "KlientID", "KlientID", domena.KlientID);
return View(domena);
}
The way it works now is, it will display a drop-down list from which I can choose TLDID by "Typ" and KlientID by "KlientID" entry in the database. Also it ask for a "Nazwa", which is name that has to be written.
I want to remove the option to choose the KlientID from the dropdownlist and instead make HttpPost take the KlientID from the link. Example :
I go to client's details page : /Klient/Details/6
I click on Add_Domain link which takes currently viewed KlientID and takes me to: /Domena/Add_Domain/6
So, my question is, how can I modify both Get and Post methods in order to create a new "domena" entry in the database to the client's id which is in the link ?
Do I have to change anything in view as well ?
Here is my current Add_Domain view fieldset :
<fieldset>
<legend>Domena</legend>
<div class="editor-label">
#Html.LabelFor(model => model.TLDID)
</div>
<div class="editor-field">
#Html.DropDownList("TLDID", String.Empty)
#Html.ValidationMessageFor(model => model.TLDID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.KlientID)
</div>
<div class="editor-field">
#Html.DropDownList("KlientID", String.Empty)
#Html.ValidationMessageFor(model => model.KlientID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Nazwa)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Nazwa)
#Html.ValidationMessageFor(model => model.Nazwa)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
Thanks in advance!
If you use the default MVC routes {controller}/{action}/{id} you should able to leverage the id parameter. The Add_Domain link in your client page would set a route value:
#Html.ActionLink("Add a domain", "Add_Domain", "Domena",
new { id = Model.KlientID }, null)
You give the GET action a parameter and set this parameter on the model:
public ActionResult Add_Domain(int id)
{
ViewBag.TLDID = new SelectList(db.TLDs, "TLDID", "Typ");
var model = new Domena { KlientID = id };
return View(model);
}
And in your view you remove label and validation message for KlientID and replace the drop down list by a hidden input:
#Html.HiddenFor(model => model.KlientID)
In the POST action you only remove the ViewBag.KlientID = ... line. The rest can remain unchanged. The MVC model binder will bind the hidden field to the domena.KlientID property.
The id parameter is a bit misused here because this id usually is related to the model the Domena controller is dealing with, so usually a DomenaID and not a KlientID. But it should still work. I would consider to use a query parameter instead to make it clearer that the last parameter in the route is a KlientID:
The action link would be:
#Html.ActionLink("Add a domain", "Add_Domain", "Domena",
new { klientID = Model.KlientID }, null)
And the GET action is:
public ActionResult Add_Domain(int klientID)
{
ViewBag.TLDID = new SelectList(db.TLDs, "TLDID", "Typ");
var model = new Domena { KlientID = klientID };
return View(model);
}
POST action is the same. The created link is then /Domena/Add_Domain?klientID=6.