ASP.NET MVC catch URL parameter in Controller - url

I've defined such a controller ViewProfile.
I want to use it for the next syntax to access public user info in my project.
/ViewProfile/Sammy
/ViewProfile/Billy
etc...
But I don't know how to handle the 2-nd parameter in URL.
I've tried to use:
[HttpGet]
public ActionResult Index(string query)
{
...
return View();
}
But in the debugger, string query is always empty.
I have read about routines mapping, but really don't understand how would it help me with the determination of id or other parameters.

I read in ASP.NET MVC Book that to get the parameter directly in the controller action just name it as ID.
ASP.NET MVC lets you easily do this without having to confi gure
anything extra. ASP .NET MVC’s default routing convention is to treat
the segment of a URL after the action method name as a parameter named
ID. If your action method has a parameter named ID, then ASP.NET MVC
will automatically pass the URL segment to you as a parameter.
I just tried a sample app and it worked fine for me. The string i entered in the URL did get passed on to the ID parameter in the action.
Also what i noticed is that you should provide your URL as viewprofile/index/1 or
viewprofile/index/somestring.
YOu seem to be skipping the action part.

Related

What is the purpose of MVC passing the current "controller" and "action" as parameter values

I had to pass an extra parameter with my action links to indicate where they came from (as I needed to change a back link in the pages accordingly).
As it was a controller name, I decided to name it controller.
e.g. a sample link might be:
#Html.ActionLink(item.Name, "Options", "Questionnaire", new {
id = item.QuestionnaireId,
controller = "templates" }, null)
The receiving action in QuestionnaireController looked like:
public ActionResult Options(int id, string controller)
When the action was hit I noticed the controller value was not template, but instead was the name of the current controller (i.e. QuestionnaireController).
As an experiment I added an action parameter e.g.:
public ActionResult Options(int id, string controller, string action)
the action value was the current action too (i.e. Options).
My work-around for this was simply to rename my parameter to source, but why does MVC bother to map the names controller and action to action parameters? I assume that would apply to any/all Route Mapping values, but what is the purpose of this?
Why does MVC bother to map the names controller and action to action parameters?
I believe it's done as part of the QueryStringValueProvider or one of the other ValueProviders (maybe the RouteDataValueProvider). ASP.Net MVC uses Convention over Configuration, so the framework uses the values provided to populate method parameters. The Controller name, Action name and even the Area name are all values provided in the Url.
I assume that would apply to any/all Route Mapping values, but what is the purpose of this?
The ValueProvider is used for Routing data to determine the matching route to use, it also happens to be the same object that provides the data to populate method parameters. The side affect you are experiencing is most likely not a feature they were trying to implement.
The DefaultModelBinder.GetValue uses the ValueProviders to locate a value and bind it to the model (or method paramater).

Html.RenderAction with Route Name

I am trying to utilize the Route attribute naming (ex: [Route(Name = "Abc123")]) in a controller action, and likewise be able to call that via Html.RenderAction, but it appears that this does not support route names. I assume this is because route names are reserved only for ones requested via HTTP and not called directly, but somewhat new to MVC so I'm at a loss.
I'm using MVC Attribute Routing entirely, and I do not have routes configured otherwise. It seems that I must define the route name, and the route name has to match the action method name. In doing so, however, I am getting naming conflicts when I try to name more than one Index.
I'm basically trying to support multiple partial views, each having their own controller, which serve as plugins/widgets on my site. So ideally each would have an action called Index.
Do you have a recommendation on how I can maintain the same naming? This allows me to call Html.RenderAction("Index", [ControllerName], [Model]) without the render name changing.
You can use attribute routing with Html.RenderAction just you have to make sure that the action name in attribute is actual Name :
[Route("Home/About")]
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
and in HTML you can have
#{Html.RenderAction("About", "home");}
It will work fine.
You should be able to do what you are trying to do with attribute routing. If you are trying to render a partial view you should be using RenderPartial instead of RenderAction.
Are you doing this between areas? I believe there are some gotcha's with making that work correctly.
Can you please post example Controller code and RouteConfig?

Attribute Routing with RoutingParameter

I currently have a set of action methods in a web api controller that use Attribute Routing.
[RoutePrefix("Paper")]...
[Route("Shape/Octagon/{id:minlength(1)}]
public IEnumerable<sampleShape> PostactionName(string id){..}
[Route("Shape/Hexagon/{id:minlength(1)}]]
public IEnumerable<sampleShape> PostactionName(string id){..}
which would work for the following URIs
api/Paper/Shape/Octagon/"1,2,3"
api/Paper/Shape/Hexagon/"3,2,1"
but becomes unusable once the id parameter becomes to long. Is there anyway to have routing use the parameter id as a form data rather than part of the URI but still keep the Route attribute.
You can use FromBody attribute to let the engine know that parameter will come from post body
[RoutePrefix("Paper")]...
[Route("Shape/Octagon"}]
public IEnumerable<sampleShape> PostactionName([FromBody]string id){..}
[Route("Shape/Hexagon"}]]
public IEnumerable<sampleShape> PostactionName([FromBody]string id){..}

Routing/Resolving asp.net mvc

I have a question that I have been thinking about.
What happens from when I enter an URL in my browser and click enter to when the code in the corresponding controller actually executes?
Let's say I have an asp.net mvc application and a trivial Controller like this:
public class HomeController : Controller
{
public ActionResult About(int id = 25)
{
//code
}
}
So if I enter like myUrl/home/about?id=56 that controller gets invoked. I know there is a routing pattern like {controller}/{action}/{id} declared by default. But if an URL matches that pattern is a controller instance created then or what happens? Is there some Resolver class or similar? Is there like a List containing all the controllers so "Home" in the URL matches the HomeController?
I know the id parameter in the controller signature will be bound to the corresponding id value in the request context with the help of model binding. But there must be a lot of other magic happening here.
Hope someone can help a fresh confused asp.net mvc user
in a nutshell:
DefaultControllerFactory finds and instantiates the controller by its name using reflection (more info)
ControllerActionInvoker finds and invokes the action by its name using reflection (more info)
Good overall description can be found here.

Overloading of public functions in Controller

I am new to MVC. I was going through the asp.net site and found this link where it stated that public methods (actions) cannot be overloaded in controller classes. However in the site it stated that it can be only be possible if i use [AcceptVerbs(HttpVerbs.Post)] with one function.
Can you please explain how does AcceptVerbs helps in overloading the function.What it actually does behind the scene?
And in one of my sample application i am able to overload the function by using [HttpPost] in one function.What else can be used for overloading?
Basically the rule is that you can handle this when it is responding to different types of requests, so Post/Get/Delete. (Any of the items in the HttpVerbs enumeration)
It is due to the way that it does resolution of the method to call in the controller, and specifying the method allows it to handle resolution.
In ASP.NET MVC, incoming request url should match action of controller. In MVC request processing pipeline, first the controller action is selected, and then the parameters for it are inspected and populated. Imagine what happened if controller had two methods with same name but different signature (overloaded).The c# compiler does not complain, as it understands the code, because it can distinguish between methods based on its parameter signature. But ASP.NET MVC request matching mechanism, as mentioned above, cannot - it first does search for action and only after action is selected, it takes look at its parameters. Because of this, "Public actions in controllers cannot be overloaded" - if there're no difference between methods(actions) other than parameters, action selection in MVC will fail to unambiguously select one. This's where ActionMethodSelectorAttribute comes into play. This is the base mechanism for developers to affect the way MVC searches for valid action in specified controller. It has the method IsValidForRequest() that tells MVC wether action can be selected for usage or not. All of [AcceptVerbs], [HttpGet], [HttpPost], [HttpPut], [HttpDelete] and [HttpNonAction] derive from this attribute. And bingo - now the method overloading is possible - although actions have got the same name, one of the attributes above (or your custom attribute derived from ActionMethodSelectorAttribute) can tell MVC wchich action to select and which one to not. And MVC now unambigously knows wchich action is valid for request. Consider example
[HttpGet]
public ActionResult Index()
{
// The above HttpGet.IsValidForRequest() called internally
by mvc will return true only if request is made via HTTP GET
}
[HttpPost]
public ActionResult Index(MyModel model)
{
// The above HttpPost.IsValidForRequest() called internally
by mvc will return true only if request is made via HTTP POST
}
// And so forth with other ActionMethodSelectorAttibute s. As you see, only one action from same named ones is valid for single request when decorated with any of builtin ActionMethodSelectorAttibute

Resources