List not beign assigned as a parameter Url.Action - c#

I'm using Url.Action to pass some paramenters to a method, like this
//Sending data
Sí
//Method
public ActionResult BorrarMensaje(int idMsg, int idMsgUsr, int idImg, List<int> idsArchs)
{
tblMensaje tblMensaje = db.tblMensaje.Find(idMsg);
tblMensajesUsuario tblMensajesUsuario = db.tblMensajesUsuario.Find(idMsgUsr);
tblImagenAdj tblImagenAdj = db.tblImagenAdj.Find(idImg);
foreach (var id in idsArchs)
{
tblArchivoAdj tblArchivoAdj = db.tblArchivoAdj.Find(id);
db.tblArchivoAdj.Remove(tblArchivoAdj);
}
//Some more code...
The values of idMsg, idMsgUsr, idImg are sent as arguments, but idsArch just doesn´t get the value of IDArchivos, when I view the count property it shows 0, (both idsArch and IDArchivos are of type List), I don't know why it isn't working, is there any alternative to do this? Thanks beforehand

For alternatives; you could write it as a Form and fields are hidden.
<form method="GET" action="#Url.Action("BorrarMensaje", "Supplier")">
<input name="idMsg" value="#item.IDMensage" hidden />
<input name="idMsgUsr" value="#item.IDMensajeUsuario" hidden />
<input name="idImg" value="#item.IDImagen" hidden />
<!-- for type list, you need to loop and specify an index -->
#for(int i = 0; i < item.IDArchivos.Count(); i++){
<!--replace PropertyName with the property name of IDArchivos that you want to submit -->
<input name="idsArchs[#i].PropertyName" hidden />
<input class="btn btn-danger" type="Submit" value="Si">
}
</form>
No changes in controller.

Related

How to overwrite one model property in ASP.Net core

I have a model with say 10 properties. A, B, C and so on...
Property A is an array.
For each value in array I generate one tag like this:
<div class="col-sm-10 row">
#foreach (var item in Model.A)
{
<div class="col-sm-1 right-buffer">
<i class="" aria-hidden="true">#item.Text</i>
</div>
}
</div>
When user clicks on some link I should redirect it to the same page, but with Some model property changed. For example:
Current url: my/controller/someaction?name=Alex&age=20&from=fr&CurrentA=
with model ?name=Alex&age=20&from=fr&CurrentA=
If user clicks on <a> with text foo it should be redirected on my/controller/someaction?name=Alex&age=20&from=fr&CurrentA=foo
then is clicks on <a> with text bar and it should be now redirected on my/controller/someaction?name=Alex&age=20&from=fr&CurrentA=bar
So entire query string (except one parameter) should be preserved to send current model state to server while I want to set one value and redirect it to the same page but with new value.
Eventually, it should acts like postback with one extra value setted to model
Is it possible or I should use JS and perform everything myself?
Manually i solved it like this:
First, create hidden fields for every property in model:
<form asp-controller="search" asp-action="index" method="get" role="form" id="searchForm" asp-antiforgery="false">
<input asp-for="SessionId" type="hidden" name="sessionId" value="#Model.SessionId" />
<input asp-for="Quantity" type="hidden" name="quantity" value="#Model.Quantity"/>
<input asp-for="SortField" type="hidden" name="sortField" value="#Model.SortField"/>
<input asp-for="IsAscending" type="hidden" name="IsAscending" value="#Model.IsAscending" />
<input asp-for="Offset" type="hidden" name="offset" value="0" />
...
</form>
Then, use JS to replace value in hidden field and then submit form. Values from inputs will be autimatically converter in query string, so everything works fine:
function sortDocuments(sortField) {
var sField = document.getElementById('SortField');
var isDescending = document.getElementById('IsAscending');
if (sField.value === sortField) {
if (isDescending.value.toUpperCase() === 'FALSE') {
isDescending.value = 'TRUE';
} else {
sField.value = 'rank';
isDescending.value = 'FALSE';
}
} else {
sField.value = sortField;
isDescending.value = 'FALSE';
}
document.getElementById('searchForm').submit();
}
Not very elegant, but it does its job.

ASP.MVC5 - Foreach with property array

Well! I'm using ASP.MVC5. What I'm trying to do is to loop an array that contains objects and each object contains array properties:
I have this class:
public class MylistModels
{
public string Subtitle { get; set; }
public string[] Question { get; set; }
}
The logic is:
I have a POST form in HTML (I can add more fields if I want):
<input type="text" placeholder="Subtitle here" name="lists[0].Subtitle" />
<input type="text" placeholder="Subtitle here" name="lists[0].Question" />
<input type="text" placeholder="Subtitle here" name="lists[0].Question" />
<input type="text" placeholder="Subtitle here" name="lists[1].Subtitle" />
<input type="text" placeholder="Subtitle here" name="lists[1].Question" />
<input type="text" placeholder="Subtitle here" name="lists[1].Question" />
<input type="text" placeholder="Subtitle here" name="lists[2].Subtitle" />
<input type="text" placeholder="Subtitle here" name="lists[2].Question" />
<input type="text" placeholder="Subtitle here" name="lists[2].Question" />
When I click in save I send it to an action:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(List<MylistModels> lists)
{
if (ModelState.IsValid)
{
//how to loop the arrays that contains a subtitle with questions array?
return RedirectToAction("Index");
}
return View();
}
When I receive it in the action, it looks like this:
I receive an array of objects and each one has your subtitle related to your questions
Obs.: the "subtitle" is always one in each object and "questions" I can have one or more.
PROBLEM:
How can I loop inside each object array and loop again in each question of this object?
I'm trying to do like this but it's not working:
SubtitleChecklist subtitleCheckList = new SubtitleChecklist();
QuestionChecklist questionChecklist = new QuestionChecklist();
foreach (var list in lists)
{
subtitleCheckList.IdChecklist = idChecklist;
subtitleCheckList.Subtitle = list.Subtitle;
db.subtitleCheckList.Add(subtitleCheckList);
db.SaveChanges();
int idSubtitleChecklist = subtitleCheckList.Id;
for (int i = 0; i < list.Question.Length; i++)
{
questionChecklist.Question = list.Question[i];
questionChecklist.IdSubtitle = idSubtitleChecklist;
db.QuestionChecklist.Add(questionChecklist);
db.SaveChanges();
}
}
Where are you instantiating questionChecklist and subtitleCheckList?
It looks like you are modifying the same objects over and over in your loops.
UPDATE 1:
Move: SubtitleChecklist subtitleCheckList = new SubtitleChecklist();
inside the outer loop and the QuestionChecklist questionChecklist = new QuestionChecklist(); into the inner loop.
Also, what result are you getting now?
You loop through lists object but you assign values and do all other stuff to one and the some object that you defined outside the loop and has nothing to do with your loop.

Form Collection issue

I have an html begin form in mvc
#using (Html.BeginForm("Search", "Reports",FormMethod.Post, new { enctype = "multipart/form-data", #class = "form-inline" }))
{
<div class="form-group">
<input type="text" class="form-control input-sm" placeholder="Value" name="SearchValue">
<input type="text" class="form-control input-sm second-value" placeholder="Value" style="display:none;" name="SearchValue1">
<button type="button" class="btn btn-default btn-Add">+</button>
</div>
<div id="othersearch"></div>
<input type="submit" value="Search" class="btn btn-primary" />
}
I want to post this form item in one controller
public ActionResult Search(FormCollection collection)
{
string searchvalue = collection.Get("SearchValue");
return View();
}
my problem is that some times second text box is not visible.. that time i dont want to collect the values.And when i press button add generate the same type of input field in the form with same name (i can add many input box). Then how can i collect all these in my controller . please help me..
You can have all the text boxes with same name "SeachValue" in your case.
string searchvalue = collection.Get("SearchValue");
This will return all text box values as comma saperated string which you can split and use further.
Check out the screen shot
the html
and the results
You can get value of all textboxes having same name using following code:
var results = ((String[])formcollection.GetValue("mytxt").RawValue).ToList();
foreach (var item in results)
{
//string name = item;
}
When ever you add a element dynamically make sure you also set it a name. so when you add a new input element it must be
<input type="text" name="NewTextBox" class="form-control input-sm" placeholder="Value" name="searchvalue">
So like this no matter how many text boxes you add, All will have same name. Once you post the form. In your controller do this.
[HTTPPOST]
public ActionResult Search(MyModel newModel,string[] NewTextBox)
{
// here as you had dynamic textbox with name = NewTextBox you
//will get all its value binded to the above string[]
}
OR
You can retrive them using Request.form["NewTextBox"] as
[HTTPPOST]
public ActionResult Search(MyModel newModel)
{
var values = Request.Form[NewTextBox];
}
But I would recommend you the first approach where you use the MVC Model Binder to take care of all the things. You will just have array of values to play with.
NOTE: Always make sure you get the names right, and use the name right while playing with MVC. As all the binding depends on the naming itself.

Mutiple buttons on MVC form - get item id in the action controller

I have a view with a list of items. Each item have a textbox and a button.
What is the best way to get the item id of the button clicked in the controller action?
I need the value from the associated textbox in the controller action, so I do not think I can use action links.
There are a number of ways to do this. Some use javascript, others don't. I personally prefer to NOT use javascript for basic functionality, unless your design is itself javascript based (such as using ajax)
For instance, you can have each item be wrapped in it's own form, with a different submit value. Just be careful not to nest forms, as that's not valid HTML.
For instance:
#using(Html.BeginForm("MyAction", "MyController", new { id=1 })) {
<input type="submit"/>
#Html.TextBox("TheValue", "One")
}
#using(Html.BeginForm("MyAction", "MyController", new { id=2 })) {
<input type="submit"/>
#Html.TextBox("TheValue", "Two")
}
public ActionResult MyAction(int? id, string TheValue) {
// if they click the first one, id is 1, TheValue = "One"
// if they click the second one, id is 2, TheValue = "Two"
}
this answer is using jquery - If you do not know how to add jQuery to your view or just simply do not want to use it let me know and I can re-work the answer
I would do something like this
<li>
<input type="text" id="1" name="1" class="whatever" />
<input type="button" value="CliCk mE" class="myButton" />
</li>
<li>
<input type="text" id="2" name="2" class="whatever" />
<input type="button" value="CliCk mE" class="myButton" />
</li>
<input type="hidden" id="myHiddenText" name="myHiddenText" />
then add this jQuery:
<script>
$(function(){
$('.myButton').click(function(){
// this is how to get the closest textbox
// you didn't show your html , maybe .prev() or .next()
var textValue = $(this).closest("input[type='text']").val();
// this sets your hidden field with the value from desired textbox
$('#myHiddenText').val(textValue);
});
});
</script>
now when you submit this form to server you can just use myHiddenText on the server
public ActionResult Index(string myHiddenText = "")
{
// hidden fields in the HTML form automatically get passed to server on submit
return View();
}
The best option would be to use jquery but if you only want to use c# I would suggest the following:
I imagine you are using some sort of repeating statement (for or foreach) to generate your textboxes, so what I would do is create a form inside that foreach this new form would contain your textbox, and foreach item you would pass the textbox id to the form submit.
something like this pseudo code:
foreach(item in array){
<form action="address/"#item.Id>
<input type="text" value=""/>
<input type="submit" value="submit textbox"/>
</>
}

Edit Dictionary in MVC3

I have a view-model "MyClass" that contains a dictionary:
Dictionary<string, bool> columns {get; set;}
and it has keys and values
columns.Add("Name", true);
columns.Add("Type", true);
now, I want to let the user edit MyClass and its dictionary.
For every key I want to show its key and to enable to check\unchek its value (true\false), such that the input's name will be the right name for editing. since the dictionary has many keys, I need to to it with "foreach" or "for".
How can I do that?
You can start from http://www.asp.net/mvc/tutorials/mvc-music-store/mvc-music-store-part-1
You need to write something like this in your View
#using (Html.BeginForm()) {
<fieldset>
<legend>MyClassViewModel</legend>
#foreach (var item in Model.Columns){
#Html.Label(item.Key)
#Html.CheckBox(item.Key, item.Value)
}
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
and your view must be bind to model in that case
#model MvcDemoApp.Models.MyClassViewModel
or as an alternative
#foreach (var item in Model.Columns)
{
#item.Key
<input type="checkbox" id="#item.Key" checked="#item.Value" />
<input type="hidden" value="#item.Value" />
<br />
}
or try using CheckBoxList custom helper by community
http://weblogs.asp.net/gunnarpeipman/archive/2011/05/05/asp-net-mvc-implementing-checkboxlist.aspx
http://www.codeproject.com/Articles/292050/MVC3-Html-CheckBoxList-custom-extension
In your case you want something like this, for the default binder to understand the name="" format:
<input type="checkbox" name="columns[0].Value" value="Key0 string value" />
<input type="checkbox" name="columns[1].Value" value="Key1 string value" />
Unfortunately the default helpers don't fully support this so you've to write the name="" explicitly. Something like:
#Html.CheckBox("columns[" + i + "].Value", new { value = columns[i].Key });
Read more about these kind of bindings on this blog post.

Categories

Resources