RouteValues without using Query String? - asp.net-mvc

I have a form generated through Razor:
using (Ajax.BeginForm("SaveProfile", "Settings", new { AccountID = Model.AccountID },
new AjaxOptions { HttpMethod = "Post" }))
The RouteValues object, new { AccountID = Model.AccountID } gets shoved into the Query String, even though I don't specify to do so anywhere in my project.
How can I pass these values to my controller action without letting them show up in the URL?

MVC model-binding will recognize values passed by the query-string or the form (post) variables.
So you could include hidden inputs in the form with the var names as the name attributes and the values as the value attributes:
#Html.HiddenFor(model => model.AccountID)

Related

Create proper link from MVC5 Ajax.ActionLink

I have an mvc view that contains a table of data. I want to include a 'Remove' button in there so users can delete records. I'm having trouble generating the proper link to go to my Delete action. In order to delete i need two values from the table, not just an id.
<td>
#Ajax.ActionLink("Delete",
"DeleteWorkItem",
"Project/Work",
new { hId = #w.ProjectId, workId = #w.WorkId},
new AjaxOptions()
{
AllowCache = false,
HttpMethod = "DELETE",
Confirm = "Are you sure you want to delete this record?"
})
</td>
is what i have so far but when the link is clicked it creates a Get request to a url and appends the two parameters in the query string. How can i get those parameter values in the url instead of the query string. Also, I want to call the http delete method but no matter what i put in that options value i get a get
My WorkController
[HttpDelete]
public ActionResult DeleteWorkItem(int hId, int workId)
{
this.brWorkManager.Delete(forhealthId, workId);
return RedirectToAction("Details");
}
my route:
routes.MapRoute(
"WorkItemDelete",
"FHProject/Work/DeleteWorkItem",
new { controller = "Work", action = "DeleteWorkItem" },
new { httpMethod = new HttpMethodConstraint("DELETE") }
);

MVC Action link with dynamic parameters

I am using MVC and my requirement is that i need to build a action link with dynamic action route value.
for example.
In my model i have the list<string> so action link should be.
../ActionMethodName/ControllerName? Item[0]=model.item[0]&Item[1]=model.Item[1]...so on.
Any Suggestion is welcome.
Several ways.
1) You can pass as array and access it.
3) You can use foreach with razor syntex to generate this type of link.
Initally , the parameter needs to be passed are hardcoded than OnClick of somthing , replace the queryString values .
#Ajax.ActionLink("Test", "actionName", "ControllerName", new { foo = "foo1", name = "ABC" }, new AjaxOptions { UpdateTargetId = "TargetName" }, new { id = "Test" })
and
$("#btnTest").click(function () {
// Replace the hardcoded parameter value desired one ... :)
$("#Test").attr('href', $("#Test").attr('href').replace("foo1", "XXX"))
});
Note:- this solution i read from asp.net forums
http://forums.asp.net/t/1841591.aspx?+pass+Javascript+value+parameter+with+Ajax+ActionLink

Using HtmlHelper.BeginForm to match a complicated route

I have a complicated route that I would like to match with an HtmlHelper.BeginForm method. I've read quite a few articles and answers on using route value dictionaries and object initializers and html attributes. But they all fall short of what I want to do...
Here is the route I want to match:
// Attempt to consolidate all Profile controller actions into one route
routes.MapRoute(
"Profile",
"{adminUserCode}/{controller}s/{customerId}/{action}/{profileId}",
new { adminUserCode = UrlParameter.Optional, controller = "Profile"},
new { adminUserCode = #"\d+", customerId = #"\d+", profileId = #"\d+" }
);
An example url for the controller & action I want to match with this would be:
http://mysite.com/123/Profiles/456/UpdatePhoneNumber/789
With the actual phone number being in the POST body
And here is the closest syntax I've come to getting right:
#using (Html.BeginForm(
"UpdatePhoneNumber",
"Profile",
new {
customerId = Model.LeadProfile.CustomerId,
profileId = Model.CustomerLeadProfileId
}))
{
<!-- the form -->
}
But this puts the parameters in the object as query string parameters, like this:
<form method="post"
action="/mvc/123/Profiles/UpdatePhoneNumber?customerId=78293&profileId=1604750">
I just tried this syntax on a whim, but it output the same thing as the other overload
#using (Html.BeginForm(new
{
controller = "Profile",
customerId = Model.LeadProfile.CustomerId,
action = "UpdatePhoneNumber",
profileId = Model.CustomerLeadProfileId
}))
I know I can just fall back on raw HTML here, but there seems like there should be a way to get the silly HtmlHelper to match more than the most basic of routes.
If you want to use complicated routes in your form you need to use the BeginRouteForm Method
#using (Html.BeginRouteForm("Profile", new
{
controller = "Profile",
customerId = Model.LeadProfile.CustomerId,
action = "UpdatePhoneNumber",
profileId = Model.CustomerLeadProfileId
}))

Binding and routing or url generation problem in Asp.NET Mvc application

In my view the call below generates url ending with Tasks/Edit but I want it to generate url like Tasks/Edit/23
<%= Html.ActionLink<TaskController>("Edit Task", (x) => x.Edit("23"))%>
in Global.asax:
string taskController = NameResolver.NameOfController<TaskController>();
string editAction = NameResolver.NameOfAction<TaskController>(x => x.Edit(null));
routes.MapRoute(
"EditTasks",
"Tasks/Edit/{id}",
new { controller = taskController, action = editAction, id = string.Empty });
I also have binding problem in this action. Values set from view is not binded to my Edit parameter. It comes null everytime and I have not set DefaultModelBinder anywhere. Here is the Edit action:
public ActionResult Edit (string id)
{
//retrieve some data and pass it to view and return view
}
So what can be the problem here? How can I solve url and binding problem? And yes I am a Asp.Net Mvc beginner :)
<%= Html.ActionLink("Task", "Edit", new { id = "2" }) %>
Although why is your id a string and not an int?

How do I access query string parameters in asp.net mvc?

I want to have different sorting and filtering applied on my view
I figured that I'll be passing sorting and filtering params through query string:
#Html.ActionLink("Name", "Index", new { SortBy= "Name"})
This simple construction allows me to sort. View comes back with this in query string:
?SortBy=Name
Now I want to add filtering and i want my query string to end up with
?SortBy=Name&Filter=Something
How can I add another parameter to list of already existing ones in ActionLink? for Example:
user requests /Index/
view has
#Html.ActionLink("Name", "Index", new { SortBy= "Name"})
and
#Html.ActionLink("Name", "Index", new { FilterBy= "Name"})
Links: The first one looks like /Index/?SortBy=Name and The second is /Index/?FilterBy=Name
I want when user pressed sorting link after he applied some filtering - filtering is not lost, so i need a way to combine my params.
My guess is there should be a way to not parse query string, but get collection of parameters from some MVC object.
so far the best way I figured out is to create a copy of ViewContext.RouteData.Values
and inject QueryString values into it.
and then modify it before every ActionLink usage.
still trying to figure out how to use .Union() instead of modifying a dictionary all the time.
<% RouteValueDictionary tRVD = new RouteValueDictionary(ViewContext.RouteData.Values); %>
<% foreach (string key in Request.QueryString.Keys )
{
tRVD[key]=Request.QueryString[key].ToString();
} %>
<%tRVD["SortBy"] = "Name"; %>
<%= Html.ActionLink("Name", "Index", tRVD)%>
My solution is similar to qwerty1000's. I created an extension method, ActionQueryLink, that takes in the same basic parameters as the standard ActionLink. It loops through Request.QueryString and adds any parameters found to the RouteValues dictionary that are not already present (so we can overwrite the original query string if needed).
To preserve the existing string but not add any keys the usage would be:
<%= Html.ActionQueryLink("Click Me!","SomeAction") %>
To preserve the existing string and add new keys the user would be:
<%= Html.ActionQueryLink("Click Me!","SomeAction", new{Param1="value1", Param2="value2"} %>
The code below is for the two usages, but it should be pretty easy to add other overloads to match the other ActionLink extensions as needed.
public static string ActionQueryLink(this HtmlHelper htmlHelper,
string linkText, string action)
{
return ActionQueryLink(htmlHelper, linkText, action, null);
}
public static string ActionQueryLink(this HtmlHelper htmlHelper,
string linkText, string action, object routeValues)
{
var queryString =
htmlHelper.ViewContext.HttpContext.Request.QueryString;
var newRoute = routeValues == null
? htmlHelper.ViewContext.RouteData.Values
: new RouteValueDictionary(routeValues);
foreach (string key in queryString.Keys)
{
if (!newRoute.ContainsKey(key))
newRoute.Add(key, queryString[key]);
}
return HtmlHelper.GenerateLink(htmlHelper.ViewContext.RequestContext,
htmlHelper.RouteCollection, linkText, null /* routeName */,
action, null, newRoute, null);
}
<%= Html.ActionLink("Name", "Index", new { SortBy= "Name", Filter="Something"}) %>
To preserve the querystring you can:
<%= Html.ActionLink("Name", "Index",
String.IsNullOrEmpty(Request.QueryString["SortBy"]) ?
new { Filter = "Something" } :
new { SortBy=Request.QueryString["SortBy"], Filter="Something"}) %>
Or if you have more parameters, you could build the link manually by using taking Request.QueryString into account.
Use ActionLinkCombined instead of ActionLink
public static string ActionLinkCombined(this HtmlHelper htmlHelper, string linkText, string actionName,
object routeValues)
{
var dictionary = new RouteValueDictionary();
foreach (var pair in htmlHelper.ViewContext.Controller.ValueProvider)
dictionary[pair.Key] = pair.Value.AttemptedValue;
if (routeValues != null)
{
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(routeValues))
{
object o = descriptor.GetValue(routeValues);
dictionary[descriptor.Name] = o;
}
}
return htmlHelper.ActionLink(linkText, actionName, dictionary);
}
MVC4
#Html.ActionLink("link text","action",new { #id = 5, #name = "textName", #abc = "abc" })
OR
#Html.ActionLink("link text", "action", "controller", new { #id = 5, #name = "textName", #abc = "abc" }, new { #class = "cssClass" })
querystring would be like:
yourDomainRout/action/5?name=textName&abc=abc
it would have class="cssClass"

Resources