An URL without a name but it has a value, is that still consider as a query string?
For example:
[HttpGet]
[Route("api/house/{Id}")]
public IActionResult GetHouseById(int Id)
link will be:
http://localhost:44565/api/house/1
Is this still consider a query string?
No, this is part of the path and in RESTful nomenclature is not a query string parameter.
Path variables are required components of the route and MUST be provided in order to identify the appropriate route. Omission of the id parameter when required by a path should cause a 404 (unless another route matches api/house).
Query string parameters however, are optional. They are the last part of the URI and occur after the ? character, such as api/house?id=1. In this style of URI, you might expect the endpoint to return the house that has an id of 1 if the query string parameter is provided, or all houses if it is omitted.
Finally, you would notate a querystring parameter via the FromUri attribute and omitting it from the path:
[HttpGet]
[Route("api/house")]
public IActionResult GetHouseById([FromUri]int id)
Related
Under ASP.NET MVC are you supposed to pick up QueryString params the same way you do in ASP.NET WebForms? or does the [AcceptVerbs(HttpVerbs.Get)] declaration get used somehow?
Query string parameters can be accepted simply by using an argument on the action - i.e.
public ActionResult Foo(string someValue, int someOtherValue) {...}
which will accept a query like .../someroute?someValue=abc&someOtherValue=123
Other than that, you can look at the request directly for more control.
I think what you are looking for is
Request.QueryString["QueryStringName"]
and you can access it on views by adding #
now look at my example,,, I generated a Url with QueryString
var listURL = '#Url.RouteUrl(new { controller = "Sector", action = "List" , name = Request.QueryString["name"]})';
the listURL value is /Sector/List?name=value'
and when queryString is empty
listURL value is /Sector/List
You can always use Request.QueryString collection like Web forms, but you can also make MVC handle them and pass them as parameters. This is the suggested way as it's easier and it will validate input data type automatically.
I recommend using the ValueProvider property of the controller, much in the way that UpdateModel/TryUpdateModel do to extract the route, query, and form parameters required. This will keep your method signatures from potentially growing very large and being subject to frequent change. It also makes it a little easier to test since you can supply a ValueProvider to the controller during unit tests.
Actually you can capture Query strings in MVC in two ways.....
public ActionResult CrazyMVC(string knownQuerystring)
{
// This is the known query string captured by the Controller Action Method parameter above
string myKnownQuerystring = knownQuerystring;
// This is what I call the mysterious "unknown" query string
// It is not known because the Controller isn't capturing it
string myUnknownQuerystring = Request.QueryString["unknownQuerystring"];
return Content(myKnownQuerystring + " - " + myUnknownQuerystring);
}
This would capture both query strings...for example:
/CrazyMVC?knownQuerystring=123&unknownQuerystring=456
Output: 123 - 456
Don't ask me why they designed it that way. Would make more sense if they threw out the whole Controller action system for individual query strings and just returned a captured dynamic list of all strings/encoded file objects for the URL by url-form-encoding so you can easily access them all in one call. Maybe someone here can demonstrate that if its possible?
Makes no sense to me how Controllers capture query strings, but it does mean you have more flexibility to capture query strings than they teach you out of the box. So pick your poison....both work fine.
This is the correct way in .NET 6 (and other netcore)
var Param = Request.Query["IndexString"];
If need to be string
string Param = Request.Query["IndexString"].ToString();
#Context.Request.Query["yourId"]
Under ASP.NET MVC are you supposed to pick up QueryString params the same way you do in ASP.NET WebForms? or does the [AcceptVerbs(HttpVerbs.Get)] declaration get used somehow?
Query string parameters can be accepted simply by using an argument on the action - i.e.
public ActionResult Foo(string someValue, int someOtherValue) {...}
which will accept a query like .../someroute?someValue=abc&someOtherValue=123
Other than that, you can look at the request directly for more control.
I think what you are looking for is
Request.QueryString["QueryStringName"]
and you can access it on views by adding #
now look at my example,,, I generated a Url with QueryString
var listURL = '#Url.RouteUrl(new { controller = "Sector", action = "List" , name = Request.QueryString["name"]})';
the listURL value is /Sector/List?name=value'
and when queryString is empty
listURL value is /Sector/List
You can always use Request.QueryString collection like Web forms, but you can also make MVC handle them and pass them as parameters. This is the suggested way as it's easier and it will validate input data type automatically.
I recommend using the ValueProvider property of the controller, much in the way that UpdateModel/TryUpdateModel do to extract the route, query, and form parameters required. This will keep your method signatures from potentially growing very large and being subject to frequent change. It also makes it a little easier to test since you can supply a ValueProvider to the controller during unit tests.
Actually you can capture Query strings in MVC in two ways.....
public ActionResult CrazyMVC(string knownQuerystring)
{
// This is the known query string captured by the Controller Action Method parameter above
string myKnownQuerystring = knownQuerystring;
// This is what I call the mysterious "unknown" query string
// It is not known because the Controller isn't capturing it
string myUnknownQuerystring = Request.QueryString["unknownQuerystring"];
return Content(myKnownQuerystring + " - " + myUnknownQuerystring);
}
This would capture both query strings...for example:
/CrazyMVC?knownQuerystring=123&unknownQuerystring=456
Output: 123 - 456
Don't ask me why they designed it that way. Would make more sense if they threw out the whole Controller action system for individual query strings and just returned a captured dynamic list of all strings/encoded file objects for the URL by url-form-encoding so you can easily access them all in one call. Maybe someone here can demonstrate that if its possible?
Makes no sense to me how Controllers capture query strings, but it does mean you have more flexibility to capture query strings than they teach you out of the box. So pick your poison....both work fine.
This is the correct way in .NET 6 (and other netcore)
var Param = Request.Query["IndexString"];
If need to be string
string Param = Request.Query["IndexString"].ToString();
#Context.Request.Query["yourId"]
My requirement is to pass a value, as a parameter, in a ServiceStack route which includes a slash like this 'SK-LOT-79-14/3/11' so I can fetch the records in my service.
Example route configuration:
[Route("/cims/qcHistoryByLot/{lotNumber}", "GET")]
Example lot number: SK-LOT-79-14/3/11
You simply need to add a * to the end of your route parameter.
[Route("/cims/qcHistoryByLot/{lotNumber*}", "GET")]
public class GetQcHistoryByLot
{
public string LotNumber { get; set; }
}
Using the asterisk * acts as a wildcard and will capture anything after /cims/qcHistoryByLot/ into LotNumber. See wildcard paths in the routing documentation for more information.
This will work for routes where you are passing the slash in the last route parameter. If you require to pass a slash in a parameter that does not come last on the route, then you will need to handle encoding the value. See my other answer here.
I have a problem with a small app i am writing. Now either my error is in my controller class or its in Routes. See images below.
Controller Class.
This is the default Route i have.
And this is the error i get when i run.
Image not very clear but it says:
The parameters dictionary contains a null entry for parameter 'playerId' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Detail(Int32)' in 'GlobalUnited.WebUI.Controllers.PlayerController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters
I read through some posts on here, one particularly:
Similar Link
What exactly does he mean when Daniel Renshaw says:
First, I would suggest you use MVC's automatic handling of parameters instead ofpulling them out of the Request yourself. Your controller action has an id parameter which seems to go ignored - use that and add others like it to get the input parameters.
Anyways, after reading that post, i changed my RouteConfig file to:
And Still i got this error. It says:
A route named 'DefaultApi' is already in the route collection. Route names must be unique.
Parameter name: name
I even tried to change my Detail action parameter to: Note the int? declaration
And i got this error after changing:
Is there something i could do to fix this, something less complicated??
All help will be appreciated, thanks.
Your parameter name playerID causes the problem here. ASP.NET MVC can only provide you a parameter named id using the default route. In your case, it cannot map the request to your action because playerID is not nullable or optional. Changing your parameter name to id will solve the problem.
public ActionResult Detail(int id)
You get the second error with route registration because you already have a route named "DefaultApi". You won't need this route if you change the parameter name(also it's registered elsewhere).
Third error is for trying to querying with the null value. ASP.NET MVC cannot map the value in URL to your parameter and you get the default value null. Since there isn't a row with a null value you get an empty sequence, then Single() method throws an exception.
As your parameter is called playerId you must pass it as a route value to the Detail action method and then check if it's null or not. This will take care of that last error you show in your question: Sequence contains no element.
Do this in the action method:
public ActionResult Detail(int? playerId)
{
if(playerId.HasValue)
{
var model = _dataSource.Players.Single(p => p.PlayerId == playerId);
return View(model);
}
// Handle the other possibility where playerId is NULL
}
For ASP.NET MVC to know how to do the correct parameter binding you must call the above action method this way, for example:
#Html.ActionLink("Player Details", "Detail", new { playerId = 1 });
Other than the duplicate route error, your errors have nothing to do with the DefaultApi route. You get a duplicate route because that route is configured in App_Start\WebApiConfig.cs
Your first problem is that you are telling MVC that you have a mandatory Route parameter called playerId, but you are not supplying this route parameter in the URL you're using. In order for this to work you would need to either alter your route to change id to playerId, or add a playerId querystring parameter to your url. If you alter the route, you would need a url like http://my.site/Player/Detail/1 (if you alter the route) or http://my.site/Player/Detail?playerId=1.
Another option is changing the parameter to public ActionResult Detail(int id) which would then use the existing default route that takes a single parameter called id and extracts it from the friendly url that ends in /1.
You could also make the method Detail(int? id), but then you would need to place a null guard around your linq query (because if you don't pass the ID on the URL it can't lookup a null record) so you would have to add this:
if (id.HasValue) {
// execute linq query
}
Alternatively, you could alter your query to return SingleOrDefault() rather than Single().
I am having a problem calling an Edit method in an application I am creating. In the view an ActionLink is clicked that should be passing the order number to the Edit method as a parameter and opening an edit page with the info for the order populated in the fields. However upon clicking the link I receive the error:
The parameters dictionary contains a null entry for parameter 'orderNum' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ViewResult Edit(Int32)' in 'AddressUpdater.WebUI.Controllers.OrderController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters
However the parameter is present in the URL. Here are the relevant method:
public ViewResult Edit(int orderNum)
{
Order order = repository.Orders.First(o => o.OrderNumber == orderNum);
return View(order);
}
If if change the parameter to int? orderNum the page will render without an error but none of the data is there.
Most probably there's something wrong with the sending of the data to the action method Edit, i.e. in your action link. Just open some devtool like Firebug or Chrome Dev tools to inspect what is being sent to the server.
When your url looks like
Edit?OrderNumber=1234
then you need to have a matching parameter on your Action method like
public ViewResult Edit(int orderNumber) {...}
Instead
Edit(int orderNum){...}
won't work. Basically url parameter name and action method parameter name have to match (not case sensitive, but the name has to match)