Accessing querystring in ASP.NET MVC6 - asp.net-mvc

I am trying to access query string parameters in my ASP.NET MVC6 applications. But it seems unlike MVC5 and web forms, QueryString doesn't have any indexer and I can't say something like:
string s = Request.QueryString["key1"] //gives error
So, my question is - how do I access query string parameters in MVC6?
Surprisingly Request.Forms collection works as expected (as in MVC5 or web forms).
Thank you.

Getting query with an indexer is supported.
See MVC code test here - https://github.com/aspnet/Mvc/blob/e0b8532735997c439e11fff68dd342d5af59f05f/test/WebSites/ControllersFromServicesClassLibrary/QueryValueService.cs
context.Request.Query["value"];
Also note that in MVC 6 you can model bind directly from query by using the [FromQuery] attribute.
public IActionResult ActionMethod([FromQuery]string key1)
{
...
}

So, my question is - how do I access query string parameters in MVC6?
You can use Request.Query which is new addition in ASPNET 5.
var queryStrings = Request.Query;
The URL I am going to try was - http://localhost:12048/Home/Index?p=123&q=456
And you can get All Keys using -
queryStrings.Keys
And then you can get the values by iterating keys -
var qsList = new List<string>();
foreach(var key in queryStrings.Keys)
{
qsList.Add(queryStrings[key]);
}

Related

Why does Odata can't parse JSON when using Extend?

I'm using OData v4 in my project Web Api (.Net Core 3.1). I'm using Devart Linqconnect to generate my model.
When I want to use "Extend" I'm getting message "can't parse JSON. Raw value".
"Select" and "Filter" working good. I'm wondering why "Extend" not working properly.
[EnableQuery(PageSize = 2)]
[HttpGet]
public IActionResult Get(ODataQueryOptions<Tasks_Object> query)
{
var items = query.ApplyTo(DBContext.Tasks_Objects.Where(i => i.Delete== null));
return Ok(items);
}
configuration of my controller/action in EDMModel.
var tasks_object = builder.EntitySet<Tasks_Object>("Task").EntityType.HasKey(e => e.ZAD_ID);
var task = builder.EntityType<Task>().HasKey(a=>a.ZAD_ID);
The problem is solved.
"Extend" not working with LinqConnect because LQ using property EntitySet<> as a relation to other table, but we can change it.
There isn't problem with EF Core because EF Core using properties as a List<> not EntityRef.

webforms using MVC routhing with Query string

I inherited a legacy webforms app that makes use of some nasty query string variables
I want to clean up the site using MVC routing, I can do this easy enough for some of the simple ones how
1 page alone call it Decision.aspx uses the following query strings.
City=Something
ShowMessages=true
CaseID = INT32
PersonID = INT32
SpectorKey = GUID
in some case the query string is a combination of many of these
like
enter code hereCity=Juno&ShowMessages=true&Personid=44
can anyone help me with this?
Just to cleat routes you can add something like this to your RouteConfig
routes.MapPageRoute(
"DecisionRoute",
"Decision/{City}/{ShowMessages}/{CaseID}/{PersonID}/{SpectorKey}", //Your URL
"~/Decision.aspx?City={City}&ShowMessages={ShowMessages}&CaseID={CaseID}&Personid={PersonID}&SpectorKey={SpectorKey}" //Actuall path
);
Note that in case that i posted all your parameters should always be. If it is not you must think how to order this paremeters.

Does breeze's withParameters method work with an OData service adapter?

I'm using OData with Entity Framework to select some records from a database. The records each have a path to a file with text content. In a single service call I'd like to be able to filter the DB records as well as filter the resulting objects based on the content of the files that the records point to. Because I can't mix LINQ to EF with LINQ to Objects, I believe the easiest way to accomplish this is to add an additional query parameter to the standard OData parameters that defines how to filter for file content after the standard odata filters have been applied.
Is looks like the entity query's "withParameters" method is the way to add a non-standard parameter but it doesn't seem to work with version 1.4.9 of breeze.
Am I doing something wrong or is there any intention to make this method work for the OData service provider?
As a workaround to this shortcoming, I've found that you can declare your entity to query with the parameters as part of the entity name, like so:
var entityId = 4;
var answerId = 6;
var entityToQuery = "MyEntity(EntityId=" + entityId + ",answerId=" + answerId + ")";
Then, build your breeze query:
var query = breeze.EntityQuery.from(entityToQuery);
This would map to an OData endpoint such as:
public IQueryable<MyEntity> GetMyEntity([FromODataUri] int entityId, [FromODataUri] int answerId)
{
}
No, you need to use the WebApi adapter. This is not a breeze shortcoming, it's a OData shortcoming because OData doesn't support this syntax.
However, the WebApi adapter does do everything you want and this is the Breeze default. Please see the docs for more information.

ASP.NET MVC Read Raw JSON Post Data

This is driving me crazy. I'm using ASP.NET MVC. I have a controller with an HttpPost action that acts as a callback URL that is called by another server (not under my control). I want to dynamically read JSON posted to it without using WebAPI or Model Binding. The URL also has a query string parameter passed to it.
The callback URL looks something like this:
http://domain.com/callback?secret=1234
I've tried reading the posted input using:
[HttpPost]
public ActionResult Callback( String secret )
{
String jsonData = new StreamReader(this.Request.InputStream).ReadToEnd();
// ...
}
However "jsonData" is always null or empty.
I just want to get the posted input and stick it into JsonFx so I can dynamically access the contents. Any ideas on how to do this the easiest possible way?
UPDATE
I've discovered the following ...
While the above DOES NOT work (jsonData will be null or empty), the following DOES if I configure what little options I have on the calling server so as to omit the "secret" query string parameter, which is about all I can do on that end since it is not my server. In this case, jsonData will have the correct posted JSON string:
[HttpPost]
public ActionResult Callback( /* String secret */ )
{
String jsonData = new StreamReader(this.Request.InputStream).ReadToEnd();
// ...
}
This is very frustrating to work around and I don't know an easy way to accept both a query string and posted JSON data on a standard MVC controller.
I have a "callback controller" with Action methods that accept various data (via GET, via form POST, via JSON POST, via JSON POST w/ a Query String, etc.) from different third-party servers. These are merchant-type callbacks where I have no control over the formats or methods used to convey information. I just need to accept the callbacks and process the information that should be there.
All of it works fine in my Controller, except the case of "JSON POST w/ a Query String".
This appears (at least to me) to be a shortcoming in standard ASP.NET MVC controllers. ???
Can anyone suggest a solution to this that can be used in a standard ASP.NET MVC controller?
Your initial approach should work if you take into consideration the fact, that ASP.NET MVC model binding has already read the stream, so you should rewind it:
[HttpPost]
public ActionResult Callback(string secret)
{
Request.InputStream.Seek(0, SeekOrigin.Begin);
string jsonData = new StreamReader(Request.InputStream).ReadToEnd();
// ...
}
Reset the position to Zero before reading the stream.
Request.InputStream.Position = 0
For ASP.NET Core 2,this works for me.
[HttpPost]
public ActionResult RawTest() {
using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
{
string content = reader.ReadToEndAsync().Result;
//...
}
//...
}

Equivalent of [Bind(Prefix = "principalId")] in MVC4 Web Api?

Background:
In MVC3, I've used the following syntax to specify custom Action parameter names:
public ActionResult ActionName([Bind(Prefix = "principalID")] int userID,
[Bind(Prefix = "dependentID")] long applicationID)
The route for this action was defined as follows (ActionNameConstraint is a custom IRouteConstraint):
routes.MapHttpRoute(
"DependantAction",
"{controller}/{principalID}/{action}/{dependentID}",
new {controller = #"[^0-9]+", action = ActionNameConstraint.Instance, dependentID = RouteParameter.Optional}
);
Question:
The BindAttribute is a System.Web.Mvc class. Is there an equivalent of this (parameter binding) in Web Api?
Of course, if there are other solutions to achieve the same result, I'd love to hear them!
You can use the System.Web.Http.FromUriAttribute attribute to specify the parameter names used for model binding.
public ActionResult ActionName(
[FromUri(Name = "principalID.userID")] int userID,
[FromUri(Name= "dependentID.applicationID")] long applicationID
)
FromUri tells model binding to examine the query string and the RouteData for the request.
I understand that in WebAPI you just use special controller class base, and special Action names, but still after all they are controllers and actions.
Did you try it and it didn't work? A quick look at this article seems to suggest model binding in general (not the specific attribute though) should work normally:
http://blogs.msdn.com/b/jmstall/archive/2012/04/16/how-webapi-does-parameter-binding.aspx
Edit:
Some say this should work with MVC only and downvoted the answer. Here you go, more references:
MS Documentation:
http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api
MSDN Blog Post
http://blogs.msdn.com/b/jmstall/archive/2012/04/16/how-webapi-does-parameter-binding.aspx
Accepted SO answer
Custom Parameter Names With Special Characters in ASP.NET Web API MVC 4
A post exploring several approaches (follow to the end)
http://blogs.msdn.com/b/jmstall/archive/2012/04/20/how-to-bind-to-custom-objects-in-action-signatures-in-mvc-webapi.aspx
Another MSDN blog post (see scenario 3)
http://blogs.msdn.com/b/hongmeig1/archive/2012/09/28/how-to-customize-parameter-binding.aspx

Resources