I have an API hosted on IIS Server.
I am making a request to a URI with below params.
{"CurrentTime":"2013-09-23 13:05:52",
"Measurement":[{"Comment":"Test Comment","RecordIdentifier":"7F54BF3C-6022-423B-8B8F-0121BA2AF516"}],
"Source":"ABC","Destination":"XYZ",
"FinalIdentifier":"058B5913-FAB9-4641-B02E-2729A02B5059"}
For the above request i can successfully deserialize the request parameters. Notice the value of "FinalIdentifier" and "Comment" parameter.
But, when Request like :
{"CurrentTime":"2013-09-23 13:05:52",
"Measurement":[{"Comment":"Âëīö","RecordIdentifier":"01CEBEAE-B99D-47B1-9C2D-1CB80069917B"}],
"Source":"ABC","Destination":"XYZ",
"FinalIdentifier":"058B5913-FAB9-4641-B02E-2729A02B5059"}
I can also deserialize this request successfully but the value of "FinalIdentifier" parameter is getting Guid.Empty (00000000-0000-0000-0000-000000000000).
Here notice the Umlet characters in 2nd request for comment field, it is some German characters (junk characters).
So, does junk characters affect the GUID value ?
But, also notice the Value of "RecordIdentifier" value in both request. It is not problem with "RecordIdentifier".
So where is the thing going wrong ?
I have below Entity for Request and parsing.
public class Measurement
{
public string Comment { get; set; }
public Guid RecordIdentifier { get; set; }
}
public class MeasurentEntityMain
{
public List<Measurement> measurement { get; set; }
public Guid FinalIdentifier { get; set; }
public string Source { get; set; }
public string Destination { get; set; }
}
Above both request i have captured from fiddler. and at API side i have tested it with debugging.
So, why this Guid field set to empty field.
I am using JSON serialization and deserialization.
I found the solution of the above said problem.
Actually i was checking Guid value at Controller side. And was getting Empty value.
I have created a HTTPhandler at my API side. This handler handles every request at routing time and then request is forwarded to respective APIController.
I have noticed at Handler side that for the Request with some Umlaut Characters, Some part of Requested data get truncated.
In Real Guid Field is of 32 Alphanumeric value and 4 dashes. But I was getting around 29 characters in Guid Value as it was last parameter in Request data some part was truncated.
When googled more i found that Umlaut characters with Length function returns length = 2.
So, For 3 Umlaut characters, 3 characters in Request data was getting truncated as i was using UTF8ENCODING and then Converting it To Byte data with Length of original string.
For more detail of this issue visit :
iOS HttpRequest with umlaut has incorrect length
Thanks a lot SO.
Related
I am facing a strange issue, sometimes i am getting the url from the sendgrid as
https://localhost:81/Activation?username=ats8#test.com&activationToken=EAAAAA
which works fine. but sometimes i am getting url which is encoded as follows,
"https://localhost:81/Activation?username=ats8%40test.com&activationToken=EAAAAA"
and my ViewModel is as follows,
public class Verification
{
[DataType(DataType.EmailAddress)]
public string Username { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[Required]
[DataType(DataType.Password)]
[Compare("Password")]
public string ConfirmPassword { get; set; }
public string ActivationToken { get; set; }
}
and the Method goes as follows,
public ActionResult Activation(string username, string activationToken)
{
var model = new Verification
{
Username = username,
ActivationToken = activationToken
};
return View(model);
}
on the 2nd case, the activationToken comes as null. how can i detect activationToken even if the url is encoded?
I believe it is not the code you pasted in question which is causing issue.
The issue may be somewhere else - probably in the view.
I have tested this code with various combination of HTTP versions / Browsers / .Net / .Net core frameworks and it is working fine.
All I can do right now is to give you pointers on where you can look for an error:
First pointer to look in model binding
While working on this sample I realized, that somewhere in your solution probably model binding is not decoding the email "#" character properly.
Note that this is applicable only if you have written any custom logic to bind the values.
I see very less probability that this pointer would help you as the input parameters to action are primitive data types.
Second Pointer To look for what you are doing in view
What i suspect is you are getting username and activation token both appropriately in second URL's case. But when you send your email ID with "%40" instead of "#" character, somehow your view is not rendering properly. This is somehow causing your activationToken to be NULL.
You should first put break-point in action method to check both UserName and ActivationToken parameters are nonempty.
If they are non empty then add HttpUtility.UrlDecode where you are assigning username as shown in below code:
var model = new Verification
{
Username = HttpUtility.UrlDecode(username),
ActivationToken = activationCode
};
This would remove %40 from mail and replace it with "#" character.
This second pointer mostly should resolve your issue.
I have a post method that accepts object containing decimal property as below
[HttpPost]
public async Task<IActionResult> Create(CreateDto createDto)
{
...do stuff here
}
public class CreateDto
{
[Required]
public string Id{ get; set; }
[Required]
public decimal? Rate{ get; set; }
}
when a value containing leading 0 being passed in for Rate field, eg: 0015, it is always coming in as 10.
Would appreciate if somebody could explain this phenomena.
The issue lies within aspnet core mvc JSON parser which allows leading zeros before numbers that are all in the range [0-7], and treats them as octal, to match the sort of results one would get using eval in javascript.
This behaviour contradicts with guildlines stated in on http://json.org:
"A number is very much like a C or Java number, except that the octal
and hexadecimal formats are not used."
and the syntax graph does not allow a number to have a leading non-significant zero.
RFC 4627 Section 2.4. agrees:
"Octal and hex forms are not allowed. Leading zeros are not allowed."
So in short, the only way is to use JSON parser that implements the Json specs correctly.
Reference: Override Json deserializing a number with a leading zero as a decimal and not an octal value
I am currently developing a ASP.NET WebAPI using JSON.NET.
I am looking to reduce traffic and want to ignore certain properties of my models for serialization, i.e. I don't want to return them in my JSON response, but I want to accept them when they are passed to my endpoint.
Example class
public class User {
public int Id { get; set; }
public string Name { get; set; }
public string Role { get; set; }
}
Use-cases
I've got a POST endpoint that takes a User model as a parameter. The request contains Name and Role. Those props should be parsed into my User.
I've got a GET endpoint that returns a User. I only want the response to contain Id and Name. Role should be ignored.
Problem
When I use the JsonIgnore attribute from JSON.NET, the property is ignored entirely. It is not serialized for my response, but the prop of my User is null, when I post the JSON User to my endpoint.
Is there a way to ignore a prop only for serialization?
Thank you in advance!
That's exactly what Data Transfer Objects are for. You should create different DTOs for different purposes (GET/POST).
Use this and pass null when you want to ignore it!
[JsonProperty("property_name", NullValueHandling=NullValueHandling.Ignore)]
I've got a RequestDto, let's say Class A Dto, it contains a self defined type property:
// C# code
public Class MyObject
{
public string A { get; set; }
public string B { get; set; }
}
public Class ADto
{
public List<MyObject> MO { get; set;}
}
When I am trying to send the Dto using Json, the Json object looks like this:
{"MO":[{"A":"String","B":"a"},{"A":"String","B":"b"}]}
but the object I am receiving will be null.
However if I change the Json string into:
{MO:[{A:"String",B:"a"},{A:"String",B:"b"}]}
I lose the quotation marks on the objects' names and it works.
The correct format of Json should include those quotation marks right?
Why is this happening?
ServiceStack does serializes and deserializes valid JSON which requires every property name to be quoted however you're saying that the text below works:
{MO:[{A:"String",B:"a"},{A:"String",B:"b"}]}
However this isn't valid JSON, it instead looks like ServiceStack's JSV Format
You haven't mentioned where you're sending the JSV Format or have provided the Raw HTTP Request (for us to work it out), but I'm assuming if you're using Postman (mentioned in your comments) than you're trying to send JSON in the ?QueryString which isn't allowed.
But ServiceStack does support sending complex object graphs on the QueryString using JSV.
Since you're sending a complex type you'd either POST the request as either JSON or www-form-urlencoded Form Data or if you want to pass it in the QueryString you need to convert it to JSV.
In future please include the Raw HTTP Request as this question lacks any context on where you're changing the JSON string, how you're trying to use it or what's actually being sent, where you're sending it to, etc - making it impossible to guess what the issue is.
Change your class to
public Class MyObject
{
public string Mobile { get; set; }
public string Name { get; set; }
}
public Class ADto
{
public List<MyObject> MO { get; set;}
}
Then your json should be
{MO:[{Mobile:"0556604",Name:"Peter"},{Mobile:"4565466",Name:"John"}]}
I'm building an ASP.NET Web API 2.
I'm serializing the JSON data to my model, which uses DataAnnotations, more specifically the Range and RegularExpression.
Everything works great, however, when the ModelState is not valid, I would like to be able to return all the invalid values back to the client.
Example:
public class Book {
...(fields removed for brevity)
[Range(0, 100)]
public int? Pages { get; set; }
}
Currently when the client sends a message with an invalid range(-1 for example), the returned message is: "The field Pages must be between 0 and 100."
I would like to return something like this: "The field Pages must be between 0 and 100. Current Value is -1."
Your Model could look like this:
[Range(0,100)]
[MinValue(0, "The field Pages must be between 0 and 100")]
public int? Pages { get; set; }