asp.net mvc optional params in razor actionLink - asp.net-mvc

I have 2 links for language switch
<a class="dropdown-item"
href="#Url.Action(ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["controller"].ToString(), new { language = "en" }, null)"
style="color:#333;">English</a>
<a class="dropdown-item"
href="#Url.Action(ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["controller"].ToString(), new { language = "ar" }, null)"
style="color:#333;">Arabic</a>
it works fine there is only controller and action in url
but when there is optional param like id for detail and edit action than it do not work as expected.
I think I have to change null (this last param) with something but I am new and googled a lot but not getting anything worthy, Please help me.
It would be better if the solution work for n number of optional params instead of only one Id, but for now that will also be acceptable.

it would be better if the solution work for n number of optional params instead of only one Id
for getting all passed querystring parameter on MVC controller side better to use
Request.QueryString
Request.QueryString is NameValueCollection and you get value passed in querystring parameter in your actionlink.
i have tried that looks like below
<a class="dropdown-item" href="#Url.Action(ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["controller"].ToString(), new { language = "ar",id="100",studentid = 1,studentName = "abc" }, null)" style="color:#333;">Arabic</a>
and your mvc Controller look like below
public ActionResult About(int id)
{
var querystring = Request.QueryString;
// in querystring you get all value like below screenshot
var studentName = querystring["studentName"]; // access parameter like
ViewBag.Message = "Your application description page.";
return View();
}
you can get all parameter that you passed in your controller.

Related

Routing with multiple parameters in ASP.NET MVC

I'm new to ASP.NET and I'm struggling to understand how routing works. In my project I've managed to create routing for; login, logout, create new user and delete user.
I've created cards containing dates and a stretched-link with the purpose to act as a booking-table (click on a card to book the said time).
View code:
When I click on the link I want to pass forward the user as a string and the time as DateTime(or string). If I replace the url.action argument "TimeSlot.ToString()" with null my routing "works", but of course with the exception that only the user is passed forward to my controller.
#model MyProject.Models.BookingSchedule
...
<div class="row" style="padding-top: 50px; border:solid">
#{ foreach (var TimeSlot in Model.GetAllAvailableTimes())
{
<div class="col-sm-1" style="padding:10px">
<div class="card text-md-center">
<a class="stretched-link" href="#Url.Action("BookTime","Booking",new { user = Model.UserName }, TimeSlot.ToString())">#TimeSlot.ToString()</a>
</div>
</div>
}
}
</div>
Controller:
So far I've just created a mockup code for my controller, its only purpose is to reload my view and redisplay available times together with the time I've booked. For now, I just want to see if my routing passes all parameters to my controller (which it doesn't):
public ActionResult BookTime(string user, string Time)
{
return View("BookingPage", bookingSchedule(user));
}
Routing:
routes.MapRoute(
"BookTime",
"Booking/{Action}/{user}/{time}",
new { controller = "Booking", action = "BookTime", user = UrlParameter.Optional, time = UrlParameter.Optional }
);
When I run my code I get the following error:
How do I create a routing with two or more parameters and what are the key aspects that I need to keep in mind?
I've tried to get knowledge from the Microsoft-docs but as I've not yet managed to overcome this issue I'm hoping someone here could explain it.
https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/routing?view=aspnetcore-6.0#attribute-routing
If I set my href to "href="#Url.Action("BookTime","Booking",new { user = Model.UserName }, TimeSlot.ToString())" then I get the error message above.
If I set href to href="#Url.Action("BookTime","Booking",new { user = Model.UserName }, null)" it will route correctly but of course it doesn't pass my parameters (see photo below):
(in the picture/code above I changed the name of the controller to BookingPage as is the name of my viewpage. I did this to rule out any routing issues)
just add an attribute route
[Route("~/Booking/BookTime/{user?}/{time?}",
public ActionResult BookTime(string user, string Time)
{
return View("BookingPage", bookingSchedule(user));
}
and fix your link
href= ( "Book Time",
"BookTime",
"Booking",
new { user = Model.UserName, time = TimeSlot.ToString() },
null )

How can send html text box value with Url.Action to controller action method input argument?

I'm new in asp.net mvc and want to read html text box value and send it to the controller action method argument,for that purpose in view page write this code:
#item.BookName
in url action in this segment:
UserID=html text box value
read value and send it to this action in controller:
public ActionResult Item(int parentPartId,int UserID)
{
}
in view page my text box is this:
<input type="text" id="USERID"/>
How can i solve that problem?thanks.
You can handle the click event of the hyperlink and inject the value from the textbox into it, like this:
HTML:
<a class="BookName" href="" data-id="#item.Id">#item.BookName</a>
Script (assumes you have jQuery, but easily re-writable if not):
$(".BookName").click(function(event)
{
event.preventDefault();
var url = '#Url.Action("Item", "Store", new {parentPartId = "PARENT_ID",UserID="USER_ID"})';
url = url.replace("USER_ID", $("#USERID").val());
url = url.replace("PARENT_ID", $(this).data("id"));
alert(url); //just for debugging
window.location.href = url;
});
You might want to check the input value is valid before you do this, but this will get you started.
Textbox value is dynamic. It depends on user input. Razor tags are compiling at the server and posting to the client.So your razor code can not understand what user going to do to your text area. You need an action trigger the method that includes determining the text box values and send to the server. You can use ajax function.
With Jquery's help.
I think #item is a loop variable.
you can change your code like below
<a onClick="myFunction(#item.id)">#item.BookName</a>
as you see i catch the id and type down as a paramenter.
this is your text area
<input type="text" id="USERID"/>
this is the javascript function that gets the textbox value and sends it to your action
function myFunction(id){
var userId = document.getElementById("UserID").value;
var data ={
parentPartId:id,
UserID:userId
}
$.ajax({ //Jquery stuff
url : '/Store/Item'
type:'POST',
data:data
dataType:'json'
success:function(){//You can handle succes scenario}
});
}
See the data's structure it is a JSON object. And parameter names are same as your actions parameters. When you send it. MVC going to understand the logic and match the parameters and values. )
You need to place form and post your data via model/Form collection
view code
#using (Html.BeginForm("SaveData", "TestCont", FormMethod.Post, new { Id = "frmTest", enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<input type="text" id="USERID" name="UserID"/>
}
controller:
[HttpPost]
[ValidateInput(false)]
public ActionResult SaveData(FormCollection form)
{
string html = Convert.ToString(form["UserID"]);
}
make sure to mark [ValidateInput(false)] otherwise it will raise error on posting html
You can place a submit button in form to post it, or in JavaScript use $('#frmTest').submit()

How do I append a variable to a string in an ActionLink?

I keep getting a Compilation Error and can't find matching overloaded method. I've tried a couple ways (variable, variable.toString). Below is the latest try.
When I click on the day (ex: 2) on the calendar the ActionLink should send the querystring: "Index?day=2".
#{ string dayAsString = startCount.ToString();}
<div><span>#Html.ActionLink(#startCount.ToString, "Index?day=" + dayAsString , "Event")</span></div>
Do this
<div>
<span>
#Html.ActionLink(startCount.ToString(), "Index", new { day = startCount })
</span>
</div>
The last parameter creates an anonymous object with the property day and value startCount. ActionLink knows to convert that into a querystring using the property name and the property value.
More details here http://msdn.microsoft.com/en-us/library/dd492936.aspx
Edit:
If you want to target a specific controller, do this
#Html.ActionLink(startCount.ToString(), "Index", new { controller = "Event", day = startCount })
You can also do this
#Html.ActionLink(startCount.ToString(), "Index", "Event", new { day = startCount }, null)
but I don't like passing null as a parameter.
Here's a list of all the overloads: http://msdn.microsoft.com/en-us/library/dd505040.aspx
You can also just cycle in the intellisense.
This should work
#Html.ActionLink(#startCount.ToString,"Index","Yourcontroller",new { day=#startCount.ToString()} , null)
replace Yourcontroller with your controller name

MVC3 Weird behavior of ActionLink with HTML 5 Data- attributes

When I use this helper method to create a link, the data attribute shows up correctly in HTML code:
#Html.ActionLink("Test", "Index", null, new { data_something = "123" })
The HTML is correct:
<a data-something="123" href="/">Test</a>
When I use the following overload of the ActionLink method (I use the T4MVC script, http://mvccontrib.codeplex.com/wikipage?title=T4MVC), the data attribute contains an underscore instead of a dash:
#Html.ActionLink("Test", MVC.Home.Index(), new { data_something = "123" })
The HTML is incorrect:
<a data_something="123" href="/">Test</a>
Is this a know bug or a feature? I searched the bugtracker (http://aspnet.codeplex.com/workitem/list/basic) but was not able to find a corresponding issue.
The following overload is working again, but I don't like to create Dictonaries all the time:
#Html.ActionLink("Test", MVC.Home.Index(), new Dictionary<string, object> {
{ "data-something", "123" }
})
for data attribute use #data_something="123" like
#Html.ActionLink("Test link",
MVC.Home.Index(),
new {controller="Home"}},new {#data_something="123"})
the above code should output
Test Link>

Actionresult doesnt get called by routelink. Formcollection the culprit?

I am fairly new to MVC. I am trying to set up a search page that searches a database and returns results. The search box is within a Html.BeginForm in my View, and looks like this:
<% using (Html.BeginForm())
{ %>
<%= Html.TextBox("searchBox", null, new { #id = "searchBox" })%>
<div id="searchButtonsDiv">
<input type="submit" value="Search" />
</div>
<% } %>
//Results are returned in a ul and orgainized
//Pagination below
<% if (Model.HasPreviousPage)
{ %>
<%= Html.RouteLink("Previous", "SearchResults", new { page = (Model.PageIndex - 1) })%>
<% } %>
<% if (Model.HasNextPage)
{ %>
<%= Html.RouteLink("Next", "SearchResults", new { formCollection = "", page = (Model.PageIndex + 1) })%>
<% } %>
I am using a FormCollection to pass to my controller that looks like this:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(FormCollection formCollection, int? page)
{
var searchString = formCollection["searchBox"];
var results = resultsRepository.GetResults();
var paginatedResults = new PaginatedList<Driver>(results, page ?? 0, pageSize);
return View(paginatedResults);
}
So far so good. When I type a word and press the submit button, Index gets called and the database returns accordingly. The ul gets populated with the results, and when there are more than pageSize results (10 in my case), the Next link shows up.
When I click "Next", the default page just loads. No pagination or anything like that. I'm pretty sure it has to do with the fact that my Index ActionResult has a FormCollection as a paramater. I thought I read somewhere that only strings/ints can be handled? Here is the MapRoute:
routes.MapRoute(
"SearchResults",
"Drivers/Index/{formCollection}/{page}",
new { controller = "Drivers", action = "Index", formCollection = "", page = "" }
);
Am I completely missing something or is there a way to handle this? I know I could just use jquery/ajax to send the string contained in the search listbox, but I don't want to do that because later I plan on adding checkbox's as means of filtering searches, etc.
I tried several different ways of setting the formCollection's value, including creating a new FormCollection that adds the searchBox, and just passing strings, etc.
The FormCollection argument in the action isn't the problem. That will always work.
It absolutely does not belong in your route, however! Just get rid of that and you'll probably solve the problem. Form elements don't go in the URI, and only stuff in the URI should be in the route.
It's not how I'd write that action signature, however. I'd suggest:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(string searchBox, int? page)
{
var results = resultsRepository.GetResults();
var paginatedResults = new PaginatedList<Driver>(results, page ?? 0, pageSize);
return View(paginatedResults);
}
Finally: You shouldn't return a View from a POST in this case. This will cause weird behavior for the user; e.g., when they press refresh their browser will warn them about re-submitting the form.
You should either:
Use a GET, not a POST for search results.
Redirect instead of returning a view.
I'd pick the first, personally.

Resources