Url.Action not passing parameter to index - c#

In my controller I have the following code:
public ActionResult Index(int? videoId, int languageId = 0)
{
//Some code
}
Then in my .chtml page I reference it like so:
#using (Html.BeginForm("Index", "VideoLanguage", FormMethod.Post))
{
#Html.Hidden("videoId", Model.VideoId)
#Html.Hidden("videoLanguageId", Model.SelectedLanguage.LanguageId)
<div>
#Html.DropDownListFor(model => model.SelectedLanguage.LanguageId, ViewData["LanguageId"] as SelectList)
</div>
<div>
Add Language
</div>
... code keeps going
So what happens when i click the button, the selected value for LanguageId from the drop down isnt passed. The original value is.

Add Language
Is set when the page loads, so the values in the HTML will be hardcoded in. What you need to do is either set the hyperlink parameters in Javascript OR use:
<input type="submit" value="Index" />
See How to pass a textbox value from view to a controller in MVC 4?

try this:
#using (Html.BeginForm("Index", "VideoLanguage", FormMethod.Post, new { videoId = Model.VideoId, languageId = Model.SelectedLanguage.LanguageId }))
{
....
}

You should pass your params to the #Html.BeginForm helper and just submit the form
#using (Html.BeginForm("Index", "VideoLanguage", FormMethod.Post, new { videoId = Model.VideoId, languageId = Model.SelectedLanguage.LanguageId }))
{
#Html.Hidden("videoId", Model.VideoId)
#Html.Hidden("videoLanguageId", Model.SelectedLanguage.LanguageId)
<div>
#Html.DropDownListFor(model => model.SelectedLanguage.LanguageId, ViewData["LanguageId"] as SelectList)
</div>
<div>
<input type="submit" value="Add Language"/>
</div>
... code keeps going
}
in your Controller you also should have two methods GET and SET with the same name:
public ActionResult Index()
{
//Here just get a view
}
[HttpPost]
public ActionResult Index(int? videoId, int languageId = 0)
{
//Here code to save in database
}

Related

How do I set the default value to a hidden input box using ASP.NET MVC?

How can do I set the default value to a hidden input box in html page using ASP.NET MVC.
Seems you are trying to set hidden value on asp.net MVC. You could
try below way.
Model:
public class HiddenValueModel
{
public int HiddenValueId { get; set; }
public String HiddenValueName{ get; set; }
}
Load Default View From Controller:
public IActionResult HiddenValueExample()
{
return View();
}
View:
#model MVCApps.Models.HiddenValueModel
#{ ViewBag.Title = " "; }
<h2>Hidden Value Example </h2>
<hr />
#using (Html.BeginForm("HiddenValueExamplePost", "controllerName"))
{
<table class="table table-sm table-bordered table-striped">
<tr><th>HiddenValueName </th><td id="HiddenValueName"> #Html.TextBoxFor(r => Model.HiddenValueName, new { #class = "form-control" })</td></tr>
<tr><th>HiddenValue Id Which Is Hidden</th><td id="HiddenValueId"><input type="hidden" id="HiddenValueId" name="HiddenValueId" value="01052022" /></tr>
</table>
<input id="Button" type="submit" value="Save" class="btn btn-primary" style="margin-left:1091px" />
}
Note: Here you could see HiddenValueId we have set the value into the feild and keep that hidden. But when you would submitted the
value to the controller it would be there. Additionally, if you want to bind the hidden value from your backend you can use this way #Html.HiddenFor(m => m.HiddenValueId, new { #value = Model.HiddenValueId} ). You could also have a
look more details on official document here
Submit Value To Controller:
[HttpPost]
public IActionResult HiddenValueExamplePost(HiddenValueModel modelWithHiddenValue)
{
return View();
}
Output:
When Bind From Controller:
public IActionResult HiddenValueExample()
{
var hiddenExamVal = new HiddenValueModel();
hiddenExamVal.HiddenValueId = 10101;
hiddenExamVal.HiddenValueName = "Test Hidden Value";
return View(hiddenExamVal);
}
Bind From Controller and submit that value again to controller:
In this case update the view like this :
#model MVCApps.Models.HiddenValueModel
#{ ViewBag.Title = " "; }
<h2>Hidden Value Example </h2>
<hr />
#using (Html.BeginForm("HiddenValueExamplePost", "StackOverFlow"))
{
<table class="table table-sm table-bordered table-striped">
<tr><th>HiddenValueName </th><td id="HiddenValueName"> #Html.TextBoxFor(r => Model.HiddenValueName, new { #class = "form-control" })</td></tr>
<tr><th>HiddenValue Id Which Is Hidden</th><td id="HiddenValueId">#Html.HiddenFor(m => m.HiddenValueId, new { #value = Model.HiddenValueId} )<br /></tr>
</table>
<input id="Button" type="submit" value="Save" class="btn btn-primary" style="margin-left:1091px" />
}
<br />
Output Using Backend Binding:
Hope it would guided you accordingly.
Creating a Hidden Field in ASP .NET MVC
Studentmodel:
public class Student{
public int StudentId { get; set; }
public string StudentName { get; set; }}
HiddenFor() in Razor View:
#model Student
#Html.HiddenFor(m => m.StudentId)
Html Result :
<input data-val="true"
data-val-number="The field StudentId must be a number."
data-val-required="The StudentId field is required."
id="StudentId"
name="StudentId"
type="hidden"
value="" />
Html.Hidden() :
#model Student
#Html.Hidden("StudentId")
Html Result :
<input id="StudentId" name="StudentId" type="hidden" value="1" />
Basic Helper (#Html.Hidden())
If you want a Hidden Field with its value set you can try this:
#Html.Hidden("Jeremy", "Thompson")
The Hidden Field's name will be "Jeremy", and the value of the Hidden Field will be "Thompson".
Strongly Typed Helper (#Html.HiddenFor()) / Model Binding
The strongly typed helper contains 2 parameters:
Hidden Field name which is the name of a Model Property.
Value of Hidden Field (if we want to set the value from the view).
Declaration of Hidden Field using strongly typed helper:
#Html.HiddenFor(m => m.StudentID, new { Value = "1" })
Ref

How to send the Model to a partial view and change it's value in the controller before it arrives to the partial view and update with ajax [duplicate]

The problem I will be describing is very similar to ones I already found (e.g. this post with nearly identical name) but I hope that I can make it into something that is not a duplicate.
I have created a new ASP.NET MVC 5 application in Visual Studio. Then, I defined two model classes:
public class SearchCriterionModel
{
public string Keyword { get; set; }
}
public class SearchResultModel
{
public int Id { get; set; }
public string FirstName { get; set; }
public string Surname { get; set; }
}
Then I created the SearchController as follows:
public class SearchController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult DisplaySearchResults()
{
var model = new List<SearchResultModel>
{
new SearchResultModel { Id=1, FirstName="Peter", Surname="Pan" },
new SearchResultModel { Id=2, FirstName="Jane", Surname="Doe" }
};
return PartialView("SearchResults", model);
}
}
as well as views Index.cshtml (strongly typed with SearchCriterionModel as model and template Edit) and SearchResults.cshtml as a partial view with model of type IEnumerable<SearchResultModel> (template List).
This is the Index view:
#model WebApplication1.Models.SearchCriterionModel
#{
ViewBag.Title = "Index";
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>SearchCriterionModel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Keyword, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Keyword, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Keyword, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="button" id="btnDisplaySearchResults" value="Search" onclick="location.href='#Url.Action("DisplaySearchResults", "SearchController")'" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
<div id="searchResults">
</div>
As you can see, I added a div with id="searchResults" below the standard template and edited the button. What I want is to display the partial view SearchResults.cshtml in the div on the bottom, but only after the button is clicked. I have succeeded in showing a partial view there by using #Html.Partial("SearchResults", ViewBag.MyData), but it is rendered when the parent view is loaded for the first time and I set ViewBag.MyData in the Index() method already, which is not what I want.
Summary: On clicking the button, I will obtain some List of SearchResultModel instances (via database access) and then the partial view should be rendered, using this newly obtained data as model. How can I accomplish this? I already seem fail at the first step, that is reacting to the button click with the above code. Right now, I navigate to the URL ~/Search/DisplaySearchResults, but of course there's nothing there and no code-behind method is called.
In traditional ASP.NET I'd just have added a server-side OnClick handler, set the DataSource for a grid and show the grid. But in MVC I already fail with this simple task...
Update: Changing the button to #Html.ActionLink I can finally enter the controller method. But naturally since it returns the partial view, it's displayed as the whole page content. So the question is: How do I tell the partial view to be rendered inside a specific div on the client side?
Change the button to
<button id="search">Search</button>
and add the following script
var url = '#Url.Action("DisplaySearchResults", "Search")';
$('#search').click(function() {
var keyWord = $('#Keyword').val();
$('#searchResults').load(url, { searchText: keyWord });
})
and modify the controller method to accept the search text
public ActionResult DisplaySearchResults(string searchText)
{
var model = // build list based on parameter searchText
return PartialView("SearchResults", model);
}
The jQuery .load method calls your controller method, passing the value of the search text and updates the contents of the <div> with the partial view.
Side note: The use of a <form> tag and #Html.ValidationSummary() and #Html.ValidationMessageFor() are probably not necessary here. Your never returning the Index view so ValidationSummary makes no sense and I assume you want a null search text to return all results, and in any case you do not have any validation attributes for property Keyword so there is nothing to validate.
Edit
Based on OP's comments that SearchCriterionModel will contain multiple properties with validation attributes, then the approach would be to include a submit button and handle the forms .submit() event
<input type="submit" value="Search" />
var url = '#Url.Action("DisplaySearchResults", "Search")';
$('form').submit(function() {
if (!$(this).valid()) {
return false; // prevent the ajax call if validation errors
}
var form = $(this).serialize();
$('#searchResults').load(url, form);
return false; // prevent the default submit action
})
and the controller method would be
public ActionResult DisplaySearchResults(SearchCriterionModel criteria)
{
var model = // build list based on the properties of criteria
return PartialView("SearchResults", model);
}
So here is the controller code.
public IActionResult AddURLTest()
{
return ViewComponent("AddURL");
}
You can load it using JQuery load method.
$(document).ready (function(){
$("#LoadSignIn").click(function(){
$('#UserControl').load("/Home/AddURLTest");
});
});
source code link

asp.net mvc 5 - Passing a ViewBag item back to the controller

I am trying to pass a ViewBag item from my view back into the post method for that view but I am having difficulty.
This is a simplified version of my methods:
public ActionResult CreateGame(int id)
{
var selPlayer = db.Players.Find(id);
if (selPlayer == null)
{
return HttpNotFound();
}
ViewBag.SelPlayerId = selPlayer.PlayerID;
PlayerGame newGame = new PlayerGame ();
return View(newGame);
}
[HttpPost]
public ActionResult CreateGame(PlayerGame newGame)
{
newGame.GameTitle = newGame.GameTitle;
newGame.GameNotes = newGame.GameNotes;
newGame.PlayerID = newGame.PlayerID;
return RedirectToAction("PlayerView");
return View(newGame);
}
This is a simplified version of my View:
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<fieldset>
<div class="editor-label">
#Html.LabelFor(model => model.GameTitle)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.GameTitle)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.GameNotes)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.GameNotes)
</div>
#Html.HiddenFor(model => model.PlayerID, new { PlayerID = ViewBag.SelPlayerId })
<p>
<input type="submit" value="Submit Game" class="btn btn-info" />
</p>
</fieldset>
</div>
}
In the POST method you can see I am trying to set the PlayerID equal to the player Id that I am passing through as ViewBag.SelPlayerID but when I look at the values that are being passed through in the debugger the id is always equal to 0 which is not right as the player I am using to test has an id of 1.
My question is how can I set the player ID for the new game I am creating equal to the player ID I am passing through as the ViewBag item, or alternatively if there is an easier way of doing this that I have overlooked.
Note: The player id is a foreign key in my Player Game model:
//Foreign Key for Player
public int PlayerID { get; set; }
[ForeignKey("PlayerID")]
public virtual Player Player { get; set; }
You usage of new { PlayerID = ViewBag.SelPlayerId } in the #Html.HiddenFor() method is setting a html attribute, not the value of the property.
If you inspect the html your generating it will be
<input type="hidden" name="PlayerID" PlayerID="1" value="0" />
Change your GET method to set the value of the property in the model (and delete the ViewBag property)
PlayerGame newGame = new PlayerGame() { PlayerID = selPlayer.PlayerID };
return View(newGame);
and in the view use
#Html.HiddenFor(m => m.PlayerID)
This:
#Html.HiddenFor(model => model.PlayerID, new { PlayerID = ViewBag.SelPlayerId })
Is creating a hidden element, bound to model.PlayerID, but with a custom Html attribute of PlayerID, you are getting 0 as thats the default value for int and you are not setting it on the model.
Based on your (simplified) code sample, you should be able to set the model PlayerID to your selected value in the get action on the controller:
newGame.PlayerID = selPlayer.PlayerID
And then
#Html.HiddenFor(m => m.PlayerID)
If for some reason you have to use ViewBag, and can't populate it on the model as above you can use #Html.Hidden instead to ensure the value comes back in.
#Html.Hidden("PlayerID", ViewBag.SelPlayerId)
Will result in:
<input type="PlayerID" value="1" />
Which should model bind back to the model. If that's not an option and to do it more manually, you can change the first parameter to something like "SelectedPlayerID" and then you can either pull out in from Request in the controller post action.
Just Try this using viewbag alone.Set hidden type element in cshtml view page.On postback you will get your player id in your argument.This will work out if you are using input type submit
<input type="hidden" id="PlayerID" name="PlayerID" value="#ViewBag.SelPlayerId"/>

Form ActionResult is not being fired

My form's ActionResult method is not properly being fired after the submit button is clicked. I've spent a few hours searching on the issue and can't find out why the ActionResult is not being fired.
Index.cshtml
#model Azure.Models.UserModel
<form method="post">
<div class="text-center">
<br/>
#using (Html.BeginForm("SubmitForm", "Home", FormMethod.Post, new { id = "submitForm" }))
{
#: Name: #Html.TextBoxFor(m => m.Name) <br /> <br />
#: Note: #Html.TextBoxFor(m => m.Note) <br /> <br />
<button type="submit" id="btnSubmit" class="btn">Submit</button>
}
</div>
</form>
HomeController.cs
public class HomeController : Controller
{
[HttpPost]
public ActionResult SubmitForm(UserModel model)
{
String name = model.Name;
String note = model.Note;
//Insert into database
return View();
}
}
I know this is probably very trivial but I can't find anything explaining why the event isn't being fired.
You are nesting a form within a form: the construct
#using(Html.BeginForm()) { }
outputs both an opening and closing tag for a form element.
If you remove the form tags wrapping your using statement, you should find it works.

How to pass values by POST in ASP.NET MVC 4

I have problem with passing values by POST in ASP.NET MVC 4
This is my action in User controller:
[HttpPost]
public string Show(int? uid, string uname)
{
return uname + uid.ToString();
}
And this is how I tried to pass values in view:
#using (Html.BeginForm("Show", "User"))
{
Html.Hidden("uid", Model.Id);
Html.Hidden("uname", Model.UserName);
<input type="submit" value="+"/>
}
html:
<form action="/User/Show" method="post"> <input type="submit" value="+"/> </form>
and:
#using(Html.BeginForm("Show", "User", FormMethod.Post, new { uid = 1, uname = "user1" }))
{
<input type="submit" value="+"/>
}
html:
<form action="/User/Show" method="post" uid="1" uname="user1"> <input type="submit" value="+"/></form>
In both ways Show action receives null instead real values.
Your HtmlHelpers are not being rendered. Use Razor syntax.
#using (Html.BeginForm("Show", "User"))
{
#Html.Hidden("uid", Model.Id);
#Html.Hidden("uname", Model.UserName);
<input type="submit" value="+"/>
}
Explanation:
Calling Html.Hidden (or Html.[anything]) is a method and usually returns an IHtmlString. Without using # infront, the engine doesn't know that you're trying to output the returned string. It just thinks you're calling a method.
This is not a good approach for an action that receives data. This approach can offer many security breaches, like data injection., essentially lots of fields.
The right thing is create a Model (or a ViewModel, if you don't want to persist the data) to make the correct guidance between View and Controller:
ViewModel:
public class MyViewModel {
public int? uid { get; set; }
public string uname { get; set; }
}
View:
#model MyProject.ViewModels.MyViewModel
#using (Html.BeginForm("Show", "User"))
{
Html.HiddenFor(model => model.uid);
Html.HiddenFor(model => model.uname);
<input type="submit" value="+"/>
}
Controller:
public ActionResult Show(int modelId) {
var model = context.Model.SingleOrDefault(m => m.ModelId == modelId);
var viewModel = new MyViewModel();
viewModel.uid = model.Id;
viewModel.uname = model.UserName;
return View(viewModel);
}
[HttpPost]
public string Show(MyViewModel viewModel)
{
return viewMode.uname + viewModel.uid.ToString();
}
You're not actually creating hidden fields in your form. You need the # in front of you Hidden helper, and drop the semi-colon at the end.
#using (Html.BeginForm("Show", "User"))
{
#Html.Hidden("uid", Model.Id)
#Html.Hidden("uname", Model.UserName)
<input type="submit" value="+"/>
}
The reason your hard-coded test didn't work is that your HTML wasn't correct. You can't just put the values you want to post on the <form> element, you need to have them as hidden fields in the form.
<form action="/User/Show" method="post">
<input type="hidden" name="uid" value="1" />
<input type="hidden" name="uname" value="user1">
<input type="submit" value="+"/>
</form>
It would be better if you could use a view model.
public class MyViewModel
{
public int? Id {get;set;}
public string UserName {get;set;}
}
public ActionResult Show()
{
return View(new MyViewModel());
}
[HttpPost]
public ActionResult Show(MyViewModel model)
{
return Content(string.format("{0} - {1}", model.Id, model.UserName));
}
(Coded in notepad so untested, but should work.)

Categories