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"]
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"]
I am new to mvc. Exploring the ways to pass value from action method of one controller to other controller. Is this possible to pass xml as value from one controller to other in httppost?
You can use Session, which is available at pretty much any time in a controller, and is very simple to use.
Session["ArbitraryKeyString"] = "Assign any object";
string arbitraryString = (string)(Session["ArbitraryKeyString"] ?? "Session returns null if key not found");
Just be sure to cast it back to the type you need, because it's stored as a Object. You can do this during server calls, since they're all simply external ways to call controller functions, and the values will persist between pages and calls.
Passing it as a parameter is probably your best option. Try using something like return RedirectToAction(ActionName, ControllerName, RouteValues);.
I'm working on a MVC web application. I need to download a file which I've stored as a byte[] stream in DB and its working fine. What I used to do on a button click I call a JS function and that calls a function in the C# backend and eventually download the file. Following is my JQuery code.
var DownloadDRR = function ()
{
var InvoiceId = $(".invoiceid").text();
location.href = location.origin + "/Invoicing/DownloadDRR?InvoiceId=" + InvoiceId;
}
And in the backend I normally get query string like this
Request.Querystring("InvoiceId");
But accidental I've discovered in my application if I write the following it still gets the InvoiceId without using Request.QueryString().
public FileResult DownloadDRR(int InvoiceId)
{
InvoicingService Invoices = new InvoicingService(Client);
byte[] RawExcel = Invoices.GetExcelService(InvoiceId);
MemoryStream stream = new MemoryStream(RawExcel);
stream.Seek(0, SeekOrigin.Begin);
return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "test.xlsx");
}
Can anyone explain why please?
MVC specifically automates a lot of that binding (model binding is the term used).
myurl.com/MyController/MyMethod?something=a&anotherthing=1234
//example 1
public ActionResult MyMethod(string something, string anotherthing)
//example2
public ActionResult MyMethod(string something, int anotherthing)
It works for both examples. Even though your querystring technically only contains string values, MVC will try to parse it to the desired type.
The only thing you need to pay attention to is that the querystring parameter names match the method's parameter names. The rest is done automagically :)
//example3
public ActionResult MyMethod(int something, int anotherthing)
In this example, something cannot be converted, as "a" cannot be put into an int. The method call will fail (expect an ASP.Net error page). However, there are ways around this:
If the type is nullable, the method will still be called, and null will be the value. int? something will be set as null if conversion fails, and this makes sure the method still gets called.
You can make it an optional parameter: MyMethod(int anotherthing, int something = 0). Notice the inversion of the parameters. Optional parameters must always be placed after normal (required) parameters! This will make sure that, when something either cannot be converted (or simply isn't part of the querystring), it will receive the default value you specified (in my example, 0)
Some remarks:
You can write custom modelbinders that go way deeper than just converting a value. However, this is not default MVC behavior. It's still good to know you can add it if you need it.
Not all parameters are always part of the querystring. If you make a POST request (as opposed to the more lax GET request), you won't see a querystring. The values are still passed, but not as part of the requested URL. This is a topic you can find tons of information on via Google.
I have a web page with a search criteria.
Once the user selects what he wants and inputs any keywords to search, he is re-directed to another page which shows the results of his search.
This session object contains all of the information of his search:
var ProjectSearchCriteria = (GBLProjectSearchCriteria) Session[GblConstants.SESSION_PROJECT_SEARCH_CRITERIA];
Is there a way for me to pass this object to an API?
Like so:
[HttpGet]
public List<string> getEpisodes(GBLProjectSearchCriteria psc)
{
var ProjectSearchResult = new ProjectSearchResultController();
var GBLProjectSearchResultListData = ProjectSearchResult.GetProjectSearchResultList(psc);
return (from GBLProjectSearchResult item
in GBLProjectSearchResultListData
select item.Title).ToList();
}
The reason why I want to do this is because the search criteria is massive and it already exists so I don't want the API to have 38032823 parameters.
Is this even possible? How would I do it? Any alternatives?
Web API binds parameters from either URI, query string, etc. or the request body. If you want to bind from any thing else, especially outside of the request message, you can create your own parameter binding. See this. The blog post creates a parameter binding for type IPrincipal but you can do something similar for `GBLProjectSearchCriteria'.
Have you tried?
getEpisodes((GBLProjectSearchCriteria) Session[GblConstants.SESSION_PROJECT_SEARCH_CRITERIA]);
One obvious question I have is, since you know the datatype already, and are type-casting to it, why are you using var?
var ProjectSearchCriteria = (GBLProjectSearchCriteria) ....
Doesn't this make more sense?
GBLProjectSearchCriteria ProjectSearchCriteria = (GBLProjectSearchCriteria) ....
I was wondering whether there is a way to create an ActionLink or similar, that changes only a few parameters of the actual query, and keeps all the other parameters intact. For example if I'm on an URL like http://example.com/Posts/Index?Page=5&OrderBy=Name&OrderDesc=True I want to change only the Page, or OrderBy parameter and keep all other parameters the same, even those I don't yet know of (like when I want to add a Search parameter or something similar too).
The header of my current action looks like this:
public ActionResult Index(int? Page, string OrderBy, bool? Desc)
and I'm only interested in the values that this controller "eats". I want however that when I extend this action (for example with a string Search parameter) the links should work the same way as before.
Here is what I did already:
Create a new RouteValueDictionary and fill it with everything from RouteData.Values
Problem: This only fills the parameters that are used in the Routing, so all other optional parameters (like Page) to the controller are lost
Add everything from HttpContext.Request.QueryString to the previous dictionary
This is what I am currently using
Problem: It might have some junk stuff, that the Controller didn`t ask for, and it doesn't work if the page was loaded using POST. You also don't have any ModelBindings (but this isn't much of a problem, because we are re-sending everything anyway)
Use HttpContext.Request.Params
Problem: this has too much junk data which imho one shouldn't add to a RouteValueDictionary that is passed to an ActionLink
So the questions:
Is there an RVD that has all the data that was passed to the Controller and was used by it?
Is this solution good, or are there any caveats I didn't think about (mainly in the context of changing a few query parameters while keeping the others intact)?
Is there a way to filter out the "junk" data from the Params object?
EDIT: Checked the RouteData.DataTokens variable, but it's usually empty, and doesn't contain everything I need. It seems to only contain parameters that are needed for the routing somewhere, but not all of the parameters.
Have a look in RouteData.DataTokens.
RouteData.DataTokens # MSDN documentation:
Gets a collection of custom values that are passed to the route handler but are not used when ASP.NET routing determines whether the route matches a request.
HTHs,
Charles