Multiple route values to the controller in MVC - asp.net-mvc

I have a got a problem while passing parameters to the controller
Here is my view:
#model IEnumerable<WebApplication2.Models.Distributer>
#foreach (var item in Model) {
#Html.ActionLink("Edit", "Edit", new{id=item.DistributerID,user=item.Name })
}
My Controller
public ActionResult Edit(int? id,string name)
{
ViewBag.name = name;
}
In the Edit view just to display the name.
My RouteMap
routes.MapRoute(
name: "Route1",
url: "{controller}/{action}/{id}/{user}",
defaults: new { controller = "Distributers", action = "Edit", id = UrlParameter.Optional,user="" }
);
Here I find that variable name in the controller is null.Inorder to test the route works.I pull the link from the loop,ie;
#model WebApplication2.Models.Distributer
#Html.ActionLink("Edit", "Edit",new{id=item.DistributerID,user=Model.Name})
This works Fine..string name=value(not null)
Why is it so??

The parameter in your route and in your call to Html.ActionLink is user, but on your action method signature, it's name. In other words, user is being passed, but your action method does nothing with it. Conversely, the name parameter is never provided. Make sure that the parameter name lines up everywhere and you're golden.

Related

Attribute routing number of parameters with 404 not found

I use AttributeRouting to set specific route for my ActionResult. I got an 404 page not found when I have this configuration:
[GET("Tender/SubmitBid/{id}/{bidId}")]
public ActionResult SubmitBid(string id, string bidId)
{
...
return View(model);
}
#using ("SubmitBid", "Tender", new { id = Model.TenderId, bidId = Model.BidId }, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
...
<button type="submit">Save</button>
}
// 404 not found
[HttpPost]
public ActionResult SubmitBid(BidViewModel model)
{
...
}
I installed a url sniffer to see the url trigger the 404 page not found and I got this: http.../Tender/SubmitBid/1/0
It supposed to be working... but I have to remove the latest parameters to reach the ActionResult and I don't know why.
Thank you for your help,
Karine
Edit
If I remove the attribute [GET("Tender/SubmitBid/{id}/{bidId}")] the page is accessible for the POST request. But the url is like http...//Tender/SubmitBid/1?bidId=0
You should not need the query string parameters since they exist in the BidViewModel you post. The point of a POST request is that you don't have query string parameters.
I think you have to use this overload of the Html.BeginForm method:
#using (Html.BeginForm("SubmitBid", "Tender", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.HiddenFor(model => model.Id)
#Html.HiddenFor(model => model.BidId)
// Other properties..
<button type="submit">Save</button>
}
Now it will post to http:localhost/Tender/SubmitBid with the properties of BidViewModel as post values, which contain Id and BidId. The signature of the POST action can stay the same:
[HttpPost]
public ActionResult SubmitBid(BidViewModel model)
{
string id = model.Id;
string bidId = model.bidId;
// ...
}
It's also possible that AttributeRouting causes this issue. Can you try this with native ASP.NET MVC routing? You could use this specific route for submitting bids:
routes.MapRoute(
name: "SubmitBid",
url: "Tender/SubmitBid/{id}/{bidId}/",
defaults: new
{
controller = "Tender",
action = "SubmitBid",
id = UrlParameter.Optional,
bidId = UrlParameter.Optional
});

Mvc: Exclude id from url

I have the next foreach in my cshtml page, it allows to me iterate in each Model item
#foreach (var item in Model)
{
<div class="date">
#item.pubDate
</div>
<a href="#Url.RouteUrl("Details", new { action = "Details", controller = "News", id = item.id, title = item.title })">
<img src="some route" alt="some alt" />
</a>
}
so now it's working fine and each element inside foreach loop has an url with something like
http://something.com/News/Details/1/first-title
http://something.com/News/Details/2/second-title
It's possible create urls with something like
http://something.com/News/Details/first-title
http://something.com/News/Details/second-title
but i can still sending id parameter to my controller ?
Thanks in advance
Add another route:
routes.MapRoute(
name: "NewsTitleRoute",
url: "News/Details/{id}/{title}",
defaults: new {
controller = "News",
action = "Details",
id = UrlParameter.Optional,
title = UrlParameter.Optional
}
);
In your controller declare the details method like this, with the two parameters as optional:
public ActionResult Details(int? id, string title="")
{
}
That route configuration and Details method will work for:
http://something.com/News/Details/
http://something.com/News/Details/1
http://something.com/News/Details/first-title
http://something.com/News/Details/1/first-title
You can just pass the title property for id parameter.
#Url.RouteUrl("Details",
new { action = "Details", controller = "News", id = item.title})
Then set type of id parameter as string in your action method:
public ActionResult Details(string id)
Or you can create custom route like in von-v's answer. Just make sure it's above the default route.

URL parameters not appearing in ASP.MVC when using variant of Html.BeginForm

I've got a view that defines a form as
<% using (Html.BeginForm( "Update", "CcisCase", FormMethod.Post, new { id = "ccisEditForm" } ))
with a submit button:
In the RegisterRoutes method (in the HttpApplication-derived class in global.asax.cs), I've got:
routes.IgnoreRoute( "{resource}.axd/{*pathInfo}" );
routes.MapRoute(
"CcisCase",
"CcisCase/{action}/{cmDatabaseId}/{caseId}",
new { Controller = "CcisCase", Action = "CcisCaseEdit", caseId = "" } );
The url generated by MVC ends with "/Update" but there are no parameters. What am I doing wrong?
Thanks,
Bob
What parameters are you expecting to see? A post does not append parameters to the querystring, a FormMethod.Get would. And, that overload with the id is the collection of HTML attributes to render for the tag (which I'm assuming you knew, but just in case).
HTH.
Your route contains a parameter {caseId} but your BeginForm only defines an id value.
new {id = "cssEditForm"}
You need something like this to include the caseId value
using (Html.BeginForm( "Update", "CcisCase", FormMethod.Post, new { caseId = 1, id = "ccisEditForm" }
If your action isn't using the id="ccisEditForm" value then you can remove that for less code clutter.
I figured out what my problem was. I had to pass the existing route data as follows:
using (Html.BeginForm( "Update", "CcisCase", ViewContext.RouteData.Values, FormMethod.Post, new Dictionary<string, object> { { "id", "ccisEditForm" } } ))

How to get the ID from URL?

I am using asp.net MVC.
I have edit page url like {controller}/Edit/2
so on the view page how can I get the ID from this URL?
I'm gonna put a link to redirect to some page with sending above ID.
EDIT
Like
<%=Html.ActionLink("name", "Action", "Controller", new{ ID = ? } ) %>
you can get it from the RouteData object
<%=Html.ViewContext.RouteData.Values["id"].ToString() %>
Put the ID in the ViewData in your action method, then your view can access the value from the ViewData.
Controller: ViewData["ID"] = id;
View: <%=Html.ActionLink("name", "Action", "Controller", new{ ID = (int)ViewData["ID"]} ) %>
...in view you get info in the model to show data so you have id in model then you can get id and pass id easy
call Model in View :
#model IEnumerable<NewsWebsite.Models.Blog>
foreach (var item in Model)
{
//your code
#Html.ActionLink("Edit", "Edit", new { id = item.BlogID })
}
Or
you can get the id from URL Like This:
Cotroller:
public ActionResult Index(int id)
{
ViewBag.ID = id;
//Your Code......
return View(...);
}
View:
#{
ViewBag.Title = "Index";
var ID = ViewBag.ID;
}
Now you have an ID in the variable
I know of two ways: You can create your link and use the "ViewData" property to pass the link to your view or you can stronglyType the ViewPage.
Here is a link on strongly typing the view.

ASP.NET MVC partial view and form action name

How do I create a partial view that has a form with assigned id?
I got as far as:
using (Html.BeginForm(?action?,"Candidate",FormMethod.Post,new {id="blah"}))
Partial view is used for both Create and Edit so first parameter ?action? will be different. I can't figure out what value of ?action? supposed to be.
UPDATE:
I guess I was not clear enough with the question. What I ended up doing is splitting Request.RawUrl to get controller name and action name:
string[] actionUrlParts = ViewContext.HttpContext.Request.RawUrl.Split('/');
using (Html.BeginForm(actionUrlParts.Length >= 2? actionUrlParts[2] : "",
actionUrlParts.Length >= 1 ? actionUrlParts[1] : "", FormMethod.Post, new { id = "blah" }))
Kind of ugly but it works. Is there a better way to get an action name inside the partial view?
Pass in the action to be performed via ViewData.
In your action that renders the view, create a ViewData item for the postback action. In your form reference this ViewData item to fill in the action parameter. Alternatively, you can create a view-only model that includes the action and the actual model as properties and reference it from there.
Example using ViewData:
using (Html.BeginForm( (string)ViewData["PostBackAction"], "Candidate", ...
Rendering actions:
public ActionResult Create()
{
ViewData["PostBackAction"] = "New";
...
}
public ActionResult Edit( int id )
{
ViewData["PostBackAction'] = "Update";
...
}
Example using Model
public class UpdateModel
{
public string Action {get; set;}
public Candidate CandidateModel { get; set; }
}
using (Html.BeginForm( Model.Action, "Candidate", ...
Rendering actions:
public ActionResult Create()
{
var model = new UpdateModel { Action = "New" };
...
return View(model);
}
public ActionResult Edit( int id )
{
var model = new UpdateModel { Action = "Update" };
model.CandidateModel = ...find corresponding model from id...
return View(model);
}
EDIT: Based on your comment, if you feel that this should be done in the view (though I disagree), you could try some logic based off the ViewContext.RouteData
<%
var action = "Create";
if (this.ViewContext.RouteData.Values["action"] == "Edit")
{
action = "Update";
}
using (Html.BeginForm( action, "Candidate", ...
{
%>
Pass nulls as action and controller. Extension will use just current action and current controller
using (Html.BeginForm(null, null, FormMethod.Post, new { id="Model" }))
Action generated for form will be the same as parent view of this partial view.
It generates
<form action="/Orders/Edit/1" id="Model" method="post">
for url http://localhost:1214/Orders/Edit/1
... and this
<form action="/Orders/Create" id="Model" method="post">
for url http://localhost:1214/Orders/Create
<% html.RenderPartial("MyUserControl", Model.ID) %>

Resources