How do you test your Request.QueryString[] variables?
Below is an extension method that will allow you to write code like this:
int id = request.QueryString.GetValue<int>("id");
DateTime date = request.QueryString.GetValue<DateTime>("date");
It makes use of TypeDescriptor
to perform the conversion. Based on your needs, you could add an overload which takes a default value instead of throwing an exception:
public static T GetValue<T>(this NameValueCollection collection, string key)
{
if(collection == null)
{
throw new ArgumentNullException("collection");
}
var value = collection[key];
if(value == null)
{
throw new ArgumentOutOfRangeException("key");
}
var converter = TypeDescriptor.GetConverter(typeof(T));
if(!converter.CanConvertFrom(typeof(string)))
{
throw new ArgumentException(String.Format("Cannot convert '{0}' to {1}", value, typeof(T)));
}
return (T) converter.ConvertFrom(value);
}
How to check that Request.QueryString has a specific value or not in ASP.NET?
You can just check for null
:
if(Request.QueryString["aspxerrorpath"]!=null)
{
//your code that depends on aspxerrorpath here
}
How to set the value of a query string in test method Moq
Query String
You will also need to mock the query string in the HttpRequestBase
object. For that you will need to build the object graph
ControllerContext
-> HttpContextBase
-> HttpRequestBase
As you are already mocking the ControllerContext
of your controller instance, you can use the following code to add the mocked query string:
var queryString = new NameValueCollection { { "code", "codeValue" } };
var mockRequest = new Mock<HttpRequestBase>();
mockRequest.Setup(r => r.QueryString).Returns(queryString);
var mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(c => c.Request).Returns(mockRequest.Object);
mockControllerContext.Setup(c => c.HttpContext).Returns(mockHttpContext.Object);
Session
For the mocked session, use the same http context configured above to also return a mock session object:
var mockSession = new Mock<HttpSessionStateBase>();
mockHttpContext.Setup(c => c.Session).Returns(mockSession.Object);
//where mockHttpContext has been created in the code for the queryString above and setup to be returned by the controller context
Then you can set the values the way you did using SetupGet
, or you can also use Setup
as in
mockSession.Setup(s => s["token"]).Returns("fooToken")
If you want to verify that a value was set on the session, you can add something like this to your assert code:
mockSession.VerifySet(s => s["token"] = "tokenValue", Times.Once);
ActionResult types
What I usually do is to cast the result to the desired type using the as
operator. It will return null if the conversion is not possible. So the assert may look like this:
ViewResult result = controller.Index() as ViewResult;
// Assert
Assert.IsNotNull(result);
Assert.AreEqual("fooView", result.ViewName);
Side Note
If you have many similar tests where the code is using the session and/or query string, there will be quite a few mock objects you need to create and configure on every test.
You could add a setup method to your test class (which is run before each test), and move there all the code that builds the object graph with the mocks. This way you have a fresh controller instance on every test method and the arrange part of every test will just need to setup the mocks behaviour and expectations.
For example, if you have this setup code in your test class:
private HomeController _homeController;
private Mock<HttpSessionStateBase> _mockSession;
private Mock<HttpRequestBase> _mockRequest;
[SetUp]
public void Setup()
{
_mockRequest = new Mock<HttpRequestBase>();
_mockSession = new Mock<HttpSessionStateBase>();
var mockHttpContext = new Mock<HttpContextBase>();
var mockControllerContext = new Mock<ControllerContext>();
mockHttpContext.Setup(c => c.Request).Returns(_mockRequest.Object);
mockHttpContext.Setup(c => c.Session).Returns(_mockSession.Object);
mockControllerContext.Setup(c => c.HttpContext).Returns(mockHttpContext.Object);
_homeController = new HomeController();
_homeController.ControllerContext = mockControllerContext.Object;
}
The code on every test will be reduced to something like this:
[Test]
public void Index_WhenNoTokenInSession_ReturnsDummyViewAndSetsToken()
{
// Arrange
var queryString = new NameValueCollection { { "code", "dummyCodeValue" } };
_mockSession.Setup(s => s["token"]).Returns(null);
_mockRequest.Setup(r => r.QueryString).Returns(queryString);
// Act
ViewResult result = _homeController.Index() as ViewResult;
// Assert
Assert.IsNotNull(result);
Assert.AreEqual("dummy", result.ViewName);
_mockSession.VerifySet(s => s["token"] = "tokenValue", Times.Once);
}
[Test]
public void Index_WhenTokenInSession_ReturnsDefaultView()
{
// Arrange
_mockSession.Setup(s => s["token"]).Returns("foo");
// Act
ViewResult result = _homeController.Index() as ViewResult;
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(String.Empty, result.ViewName);
}
Where those tests are testing this dummy Index method
public ActionResult Index()
{
if (Session["token"] == null)
{
if (Request.QueryString["code"] != null)
{
Session["token"] = "tokenValue";
return View("dummy");
}
}
return View();
}
How can I get query string values in JavaScript?
Update: Jan-2022
Using Proxy()
is faster than using Object.fromEntries()
and better supported
const params = new Proxy(new URLSearchParams(window.location.search), {
get: (searchParams, prop) => searchParams.get(prop),
});
// Get the value of "some_key" in eg "https://example.com/?some_key=some_value"
let value = params.some_key; // "some_value"
Update: June-2021
For a specific case when you need all query params:
const urlSearchParams = new URLSearchParams(window.location.search);
const params = Object.fromEntries(urlSearchParams.entries());
Update: Sep-2018
You can use URLSearchParams which is simple and has decent (but not complete) browser support.
const urlParams = new URLSearchParams(window.location.search);
const myParam = urlParams.get('myParam');
Original
You don't need jQuery for that purpose. You can use just some pure JavaScript:
function getParameterByName(name, url = window.location.href) {
name = name.replace(/[\[\]]/g, '\\$&');
var regex = new RegExp('[?&]' + name + '(=([^]*)|&|#|$)'),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, ' '));
}
Usage:
// query string: ?foo=lorem&bar=&baz
var foo = getParameterByName('foo'); // "lorem"
var bar = getParameterByName('bar'); // "" (present with empty value)
var baz = getParameterByName('baz'); // "" (present with no value)
var qux = getParameterByName('qux'); // null (absent)
NOTE: If a parameter is present several times (?foo=lorem&foo=ipsum
), you will get the first value (lorem
). There is no standard about this and usages vary, see for example this question: Authoritative position of duplicate HTTP GET query keys.
NOTE: The function is case-sensitive. If you prefer case-insensitive parameter name, add 'i' modifier to RegExp
NOTE: If you're getting a no-useless-escape eslint error, you can replace name = name.replace(/[\[\]]/g, '\\$&');
with name = name.replace(/[[\]]/g, '\\$&')
.
This is an update based on the new URLSearchParams specs to achieve the same result more succinctly. See answer titled "URLSearchParams" below.
How to get GET (query string) variables in Express.js on Node.js?
In Express it's already done for you and you can simply use req.query for that:
var id = req.query.id; // $_GET["id"]
Otherwise, in NodeJS, you can access req.url and the builtin url
module to url.parse it manually:
var url = require('url');
var url_parts = url.parse(request.url, true);
var query = url_parts.query;
Most elegant way of checking the value of a query string parameter if not null?
I thought first of offering
if ((Page.Request.QueryString["ParamName"] ?? "") == expectedResult) {
but quickly realized that with strings, comparing some string with null is fine, and will produce false, so really just using this will work:
if(Page.Request.QueryString["ParamName"] == expectedResult)
//Do something spectacular
how does Request.QueryString work?
The HttpRequest
class represents the request made to the server and has various properties associated with it, such as QueryString
.
The ASP.NET run-time parses a request to the server and populates this information for you.
Read HttpRequest Properties for a list of all the potential properties that get populated on you behalf by ASP.NET.
Note: not all properties will be populated, for instance if your request has no query string, then the QueryString
will be null/empty. So you should check to see if what you expect to be in the query string is actually there before using it like this:
if (!String.IsNullOrEmpty(Request.QueryString["pID"]))
{
// Query string value is there so now use it
int thePID = Convert.ToInt32(Request.QueryString["pID"]);
}
Get full query string in C# ASP.NET
Try Request.Url.Query
if you want the raw querystring as a string.
In Go's http package, how do I get the query string on a POST request?
A QueryString is, by definition, in the URL. You can access the URL of the request using req.URL
(doc). The URL object has a Query()
method (doc) that returns a Values
type, which is simply a map[string][]string
of the QueryString parameters.
If what you're looking for is the POST data as submitted by an HTML form, then this is (usually) a key-value pair in the request body. You're correct in your answer that you can call ParseForm()
and then use req.Form
field to get the map of key-value pairs, but you can also call FormValue(key)
to get the value of a specific key. This calls ParseForm()
if required, and gets values regardless of how they were sent (i.e. in query string or in the request body).
Related Topics
Using C# to Search a CSV File and Pull the Value in the Column Next to It
JSON Deserialization - Map Array Indices to Properties with JSON.Net
Overriding Fields or Properties in Subclasses
Wcf - Design Parameter Decision
Best Practices: Throwing Exceptions from Properties
What's the Difference Between Utf8/Utf16 and Base64 in Terms of Encoding
How to Include Subclasses in Swagger API Documentation/ Openapi Specification Using Swashbuckle
The Difference Between Virtual, Override, New and Sealed Override
C#: How to Convert a List of Objects to a List of a Single Property of That Object
Is There a Port of Memcache to .Net
C# Constructing Parameter Query SQL - Like %
How to Get the Text of a Messagebox When It Has an Icon
Unit Testing That Events Are Raised in C# (In Order)
How to Get the Last Four Characters from a String in C#
How to Use System.Net.Httpclient to Post a Complex Type