Unable to cast object of type 'System.String' to type 'System.Int32'. on Blazor/Razor routing parameters - razor

I have tried to call a page with /somepage/{Id} where Id is a [Parameter] with a int property and the route is called as a string, it shouldn't be impicitly converting string to int? why it it wouldnt work at all? I am expecting it would recognize the parameter as it is...
what should I try to have the routing middleware to recognize the parameter ? even in MVC this works just fine...
the page routing
#page "/EditEmployee/{Id}"
the link
Edit
the parameter in the page
[Parameter]
public int Id { get; set; }
the result is an exception and the page doesnt load

Make it
#page "/EditEmployee/{Id:int}"

Related

.NET Core Blazor App: How to pass data between pages?

I just started learning how to make websites with using Blazor template. But I don't know how to pass the data from one page to another. It is a bit different than .NET CORE MVC web application and I couldn't find an example for this.
<p>Solve This problem: #rnd1 * #rnd2 = ?</p>
<input type="text" name="result" bind="#result" />
<input type="button" onclick="#calculate" value="Submit" />
I want to send the value in my textbox to the another page. How can I do this?
You can pass it as a parameter.
In the page you want to navigate to, add the parameter to your route:
#page "/navigatetopage/{myvalue}"
and make sure the parameter exists in that page:
[Parameter]
private string myvalue{ get; set; }
In the same page you can pick that up in:
protected override void OnParametersSet()
{
//the param will be set now
var test = myvalue;
}
Now in your start page make sure to navigate to the second page including the value:
uriHelper.NavigateTo($"/navigatetopage/{result}");
That uriHelper needs to be injected like this:
#inject Microsoft.AspNetCore.Blazor.Services.IUriHelper uriHelper
UPDATE PREVIEW-9
on preview-9 you should use navigationManager instead of uriHelper, it also has a NavigateTo method
#inject Microsoft.AspNetCore.Components.NavigationManager navigationManager
More recent versions support the following:
The page you are navigating from:
<NavLink href="/somepage/1">Navigate to page 1</NavLink>
The page you are navigating to:
#page "/somepage/{childId:int}"
<h1>Some Page</h1>
<p role="status">Current child: #childId</p>
#code {
[Parameter]
public int childId { get; set; }
}
I personally prefer to add query string to the url.
For example when I want to pre-select tab when page is loaded:
Call the url like http://localhost:5000/profile?TabIndex=2
In your code you can parse this using NavigationManager and QueryHelpers
Add using Microsoft.AspNetCore.WebUtilities;
Then override one of the lifecycle methods and parse the query parameter
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
Uri uri = this.Nav.ToAbsoluteUri(this.Nav.Uri);
if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("TabIndex", out StringValues values))
{
if (values.SafeAny())
{
_ = int.TryParse(values.First(), out int index);
this.TabIndex = index;
}
}
}
}
I got an error while testing Flores answer in the page were we passing a data
Below is the current Page
#inject Microsoft.AspNetCore.Components.NavigationManager navigationManager
Int64 Id {get;set;}
<MudMenuItem #onclick="#(() => NextPage(#Id))">Next Page</MudMenuItem>
//So Here I am passing the ID which is long
private void NextPage(Int64 Id){
navigationManager.NavigateTo($"/secondPage/{Id}");
}
Second Page
Instead of using -Id only you need to cast it to long or else it throws an error
-From
#page "/pettyCashAuditTrail/{Id}"
-To
#page "/pettyCashAuditTrail/{Id:long}"
[Parameter] public Int64 Id{ get; set; }

How to Bind Delta<T> in web api2 odata 3 controller

So I'm building out new dataservices, and figured I'd use web api odata. So I added a controller to my project using the scaffolding to generate actions for my entity framework model classes. Everything worked great until I tried the generated put or patch methods. The guid Id from the url binds, but no matter what I try I can't bind the Delta variable. It's always null. After a day of googling i can't find anything newer than about 2011 and those solutions don't work. Does anybody know how to get these to bind?
method signature
[AcceptVerbs("PATCH", "MERGE")]
public async Task<IHttpActionResult> Patch([FromODataUri] Guid key, Delta<AttachmentProposal> patch)
my web api config
public static void Register(HttpConfiguration config)
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<AttachmentProposal>("AttachmentProposals");
builder.EntitySet<AttachmentAction>("AttachmentActions");
config.Routes.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());
config.MapHttpAttributeRoutes();
my model is something like
public Guid Id { get; set; }
public string name { get; set; }
public DateTime createDate { get;set; }
public virtual HashSet<AttachmentActions> {get; set;}
if it makes any difference i always try to send up json. typical request body's i've tried are like
{ name: 'some name' }
or
{ every: 'value', single: 'value', property: 'value', on: 'value', my: 'value' model: 'value' }
figured out the answer by making a console app with a reference to the service and watching the traffic. If anybody else is having this problem try adding odata.type: "what ever the type of your object is" to the json in the request

"Cannot populate JSON array for type" When trying insert data

Update: After all day messing with this, I fixed it.
I Changed my mobileserviceclient URL to include https instead of HTTP.
I think this was causing my post to instead be a get request that returned an array of "Comment" and tried to parse it to a single "Comment" therefore the error.
Having trouble debugging this, I have the following table/class:
public class Comment
{
public string Content { get; set; }
public string UserId { get; set; }
public string MenuItemId { get; set; }
}
Using AzureMobileServiceClient I can get data from the Azure Mobile App into my Xamarin App so the JSON returned from the client must be getting deserialized into my Comment type but when I try to add data using the following code:
var comment = new Comment
{
Content = NewComment,
MenuItemId = Item.Id,
UserId = App.CloudService.CurrentUser.UserId
};
await App.CloudService.client.GetTable<Comment>().InsertAsync(comment);
I get the error "Cannot populate JSON array onto type 'Comment'"
I can insert the data fine using postman definitely something wrong on the client-side. I saw one other question on this and they said they fixed it by deleting the project and remaking but I'd rather figure out what is actually happening.

how json parameter pass in asp.net web api action method

My asp.net web api is an standalone application,face problem to pass json sa a parameter.My api method is bellow
[Route("api/UniqueUser/{userInfo}")]
public HttpResponseMessage GetUniqueUserByEmail(string userInfo)
{
}
In above parameter userInfo is a josn like bellow
{"UserInfo":[{"Id":1,"UserName":"Jxj Bdn","Email":"a#a.com"}]}
When I put this in my browser url show me bellow error
JSON data should go in the body of the request for it to be deserialized, not in the query string/browser URL.
Also, 'string userInfo' will not work as you expect. You can define a class that represents the parameters of your JSON object and it will work correctly.
This would work, for example:
public class UserInfo
{
public int Id { get; set;}
public string UserName { get; set;}
public string Email { get; set;}
}
and change this line:
public HttpResponseMessage GetUniqueUserByEmail(UserInfo userInfo)
Edit:
If it's a url that someone needs to pass in you use routing:
https://site/api/UniqueUser/1/Jxj Bdn/a#a.com
And in your controller:
[Route("api/UniqueUser/{id}/{userName}/{email}")]
public HttpResponseMessage GetUniqueUserByEmail(int id, string userName, string email)
Have a look here to see how to do this with traditional query string parameters too:
http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api
I would strongly suggest using the first method though, it gives you a strongly type object and is a lot easier to deal with if details change, and you get the benefit of the build in model validation.
Can you not make a simple HTML form for your clients to use?

Configure ServiceStack.Text to throw on invalid JSON

Is it possible to make the ServiceStack.Text library throw when attempting to deserialize invalid JSON. By default it looks as if invalid JSON is just ignored, so that the result object contains null values.
When I attempt to deserialize this json (a " is missing after MongoConnectionString)
{
"MongoDb": {
"MongoConnectionString:"mongodb://localhost:27017/x",
"MongoDatabase":"x",
"MongoSafeModeEnabled":true,
"MongoSafeModeFSync":true,
"MongoSafeModeWriteReplicationCount":
"MongoSafeModeWriteTimeout":"00:00:00"
},
by doing this: JsonSerializer.DeserializeFromString(json);
where
public class Configuration {
public class MongoDbSettings
{
public string MongoConnectionString {get;set;}
public string MongoDatabase {get;set;}
public bool MongoSafeModeEnabled {get;set;}
public bool MongoSafeModeFSync {get;set;}
public int MongoSafeModeWriteReplicationCount {get;set;}
public TimeSpan MongoSafeModeWriteTimeout {get;set;}
}
}
I get a Configuration object where MongoDbSettings is null. I would prefer to get an exeception in this case. Is this possible?
At the moment the ServiceStack serializers are optimized for resilience, i.e. deserialize as much as possible without error.
I'd recommend adding some of your own validation checking post serialization to work out which fields weren't deserialized correctly.
You could also submit a pull-request to the ServiceStack.Text project that supports an opt-in flag (i.e. on JsConfig) to change the behavior to throw exceptions.