how to remove validate input parameters on a action? - asp.net-mvc-4

i want to redirect from on page to another on mvc and pass some parameter and get them on second page.
my parameter is something like this
?id=UXodaA54Iqo+gId3avkIqA
but when i get this parameter on the second the page some characters like "+" removed
and the parameter has been changed to this
UXodaA54Iqo gId3avkIqA
my action is
[ValidateInput(false)]
public ActionResult test(string id)
{
return view();
}
what is the best way to handle it just for this action because i do not want to put some thing like this on my web config
<httpRuntime requestValidationMode="2.0" />

This is not releated to validation. A + character in a query string parameter is seen as a space. Use HttpUtility.UrlPathEncode() to encode your parameter.

Related

sitefinity ActionResult missing query string

I have widget and in the ActionResult method it get the query string as parameters. The widget takes the query string and calls a API. Is there anyway I can display a message to the view if its missing the query string?
Code
public ActionResult Index(string UserId, string BlogId)
Yep, do whatever you want
if(String.IsNullOrEmpty(UserId)){
// you get the idea
}
I would do one of the following
Add a property to the model, then handle that state in the view
Load a custom view that's just the message (cleanest)
Check for the empty querystring and do a return this.RedirectPermanent(url); to add the querystring to the page so there's no way it loads without something.

RazorPages anchor tag helper with multiple parameters

Here's the RazorPages page I'm trying to make a link to:
#page "{ReportId:int}/{SicCode:alpha?}"
This works
<a asp-page="/ReportSics" asp-route-ReportId="3">rs1</a>
it produces
rs1
But this produces a blank href.
<a asp-page="/ReportSics" asp-route-ReportId="3" asp-route-SicCode="10">rss2</a>
That is: the tag helper works with one parameter but not with two.
Why?
Is it possible to make it work?
(I have another page with the same #page but with the second parameter not optional and it appears to be impossible to create a link to it.)
Furthermore, requesting Page/2/M works, but Page/2/12 returns 404. Why? (The second parameter is a string that can sometimes be a number, but it always treated as a string.)
From the learn.microsoft.com webpage asp-all-route-data offers the following:
asp-all-route-data
The asp-all-route-data attribute supports the creation of a dictionary of key-value pairs. The key is the parameter name, and the value is the parameter value.
In the following example, a dictionary is initialized and passed to a Razor view. Alternatively, the data could be passed in with your model.
#{
var parms = new Dictionary<string, string>
{
{ "speakerId", "11" },
{ "currentYear", "true" }
};
}
<a asp-route="speakerevalscurrent"
asp-all-route-data="parms">Speaker Evaluations</a>
The preceding code generates the following HTML:
Speaker Evaluations
Extension: From here the parameters can be accessed either explicitly in the parameter list of the method:
public IActionResult EvaluationCurrent(int speakerId, string currentYear)
or as a collection (See response: queryString:
public IActionResult EvaluationCurrent()
{
var queryString = this.Request.Query;
}
This works
Yes it works because it produces a route that is similar to this baseUrl/reportsics/?reportId=5
And the other produces a URL that is similar to this baseUrl/reportsics/?reportId=5&sicCode=678 and then it doesn't match your route definition. I think you should try this.
Experimental
asp-page="/reportSics/#myId/#sicCode
Though this would not be the right way to do what you're thinking. If you really want to change your URL structure, why not do url-rewrite?
Edit.
Form your recent comments, seems you want to pass many parameters in your action method and not targeting URL structure. Then I recommend you just
public IActionResult(string ReportId, string sicCode)
{
//......
}
//And the your URL target
<a asp-page="ReportSics" asp-route-ReportId="55" asp-route-sicCode="566" ></a>
And then it will match the route. I think you should remove that helper you placed after your #page definition and try it out if this is what you have already done and the problem persists.
It turns out that if a parameter has the constraint :alpha then it only works if the value being passed can not be parsed as an int or float.

Blazor Application - pass a Query String to the app on startup

I have a Blazor application how can I pass a Query String to the app on startup?
I want to pre-populate a form field and query a database with the query string value on startup.
Something like this `http://www.somesite.com?Company=Google
I have seen the following - using query string in pages. But how to you accept the query string on start up?
https://www.mikesdotnetting.com/article/340/working-with-query-strings-in-blazor
Where in the app page or code - Startup.cs / Program.cs - do you check for the query string.
thx in advance
This Microsoft article will explain it better than I can:
https://learn.microsoft.com/en-us/aspnet/core/blazor/routing?view=aspnetcore-3.1
Here is a summary of relevant parts.
On your page you can have this:
#page "/Users/{text}"
Then in your code create a parameter:
[Parameter]
public string Company { get; set; }
Then if you navigate to: yoursite.com/Users/Google
your parameter will be populated, and you can do any loading / or other prerendering in OnInitializedAsync method.
// this is from one of my projects
protected override async Task OnInitializedAsync()
{
// load the Categories
this.Categories = await HelpCategoryService.GetHelpCategoryList();
}
You can have multiple routes on the same page, so you could have:
#page "/Users/
#page "/Users/{Company:string}"
Maybe that points you in the right direction.

How to work around "A catch-all parameter can only appear as the last segment of the route template."

If I have a controller with an action method that uses attribute based routing and declare it like this, all is well:
[HttpGet]
[Route("/dev/info/{*somevalue}")]
public IActionResult Get(string somevalue) {
return View();
}
I can route to the above action method for example by specifying a url that ends in /dev/info/hello-world or /dev/info/new-world
However my business requirement is to have a urls that look like this: /dev/hello-world/info or /dev/new-world/info And there is an endless set of such urls that all need to route to the same action method on the controller.
I thought to set up the attribute based route on the action method as follows:
[HttpGet]
[Route("/dev/{*somevalue}/info/")]
public IActionResult Get(string somevalue) {
return View();
}
But when I do that I get the following error as soon as the web project runs:
An unhandled exception occurred while processing the request.
RouteCreationException: The following errors occurred with attribute routing information:
For action: 'App.SomeController.Get (1-wwwSomeProject)'
Error: A catch-all parameter can only appear as the last segment of the route template.
Parameter name: routeTemplate
Microsoft.AspNetCore.Mvc.Internal.AttributeRoute.GetRouteInfos(IReadOnlyList actions)
There has to be some way to work around this error. Know a way?
Middleware is the way to achieve this.
If you need an api response is easy to implement inline.
if (app.Environment.IsDevelopment())
{
app.Use(async (context, next) =>
{
Console.WriteLine(context.Request.Path);
if (context.Request.Path.ToString().EndsWith("/info"))
{
// some logic
await context.Response.WriteAsync("Terminal Middleware.");
return;
}
await next(context);
});
}
If you need to call a controller you can simply edit request path via middleware to achieve your requirement.
You can find an example here: https://stackoverflow.com/a/50010787/3120219
It is possible to achieve this by using the regular expression:
[HttpGet]
[Route(#"/dev/{somevalue:regex(^.*$)}/info/")]
public IActionResult Get(string somevalue)
{
return View();
}
About routing constrain using the regular expressions see in the documentation: Route constraint reference
The regular expression tokens explanation:
Token
Explanation
^
Asserts position at start of a line
.
Matches any character (except for line terminators)
*
Matches the previous token between zero and unlimited times, as many times as possible
$
Asserts position at the end of a line
If it's required to have the “world”suffix in the second segment then add this suffix to the pattern like the following: [Route(#"/dev/{somevalue:regex(^.*world$)}/info/")].

Specifyng a default message for Html.ValidationMessageFor in ASP.NET MVC4

I want to display an asterisk (*) next to a text box in my form when initially displayed (GET)
Also I want to use the same view for GET/POST when errors are present) so For the GET request
I pass in an empty model such as
return View(new Person());
Later, when the form is submitted (POST), I use the data annotations, check the model state and
display the errors if any
Html.ValidationMessageFor(v => v.FirstName)
For GET request, the model state is valid and no messages, so no asterisk gets displayed.
I am trying to workaround this by checking the request type and just print asterisk.
#(HttpContext.Current.Request.HttpMethod == "GET"? "*" : Html.ValidationMessageFor(v=> v.FirstName).ToString())
The problem is that Html.ValidationMessageFor(v=> v.FirstName).ToString() is already encoded
and I want to get the raw html from Html.ValidationMessageFor(v=> v.FirstName)
Or may be there is a better way here.
1. How do you display default helpful messages (next to form fields) - such as "Please enter IP address in the nnn.nnn.nnn.nnn format) for GET requests and then display the errors if any for the post?
2. What is the best way from a razor perspective to check an if condition and write a string or the MvcHtmlString
Further to my last comment, here is how I would create that helper to be used:
public static class HtmlValidationExtensions
{
public static MvcHtmlString ValidationMessageForCustom<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, string customString)
{
var returnedString = HttpContext.Current.Request.HttpMethod == "GET" ? customString : helper.ValidationMessageFor(expression).ToString();
return MvcHtmlString.Create(returnedString);
}
}
And it would be used like this #Html.ValidationMessageForCustom(v=> v.FirstName, "Please enter IP address in the nnn.nnn.nnn.nnn format")