my JSON string is like this.
string jsonstring1 = #"{'data':'N'}";
string jsonstring2 = #"{'data':[{'name':'jack','address':'la'}]}";
string jsonstring3 = #"{'data':{'flag':true}}";
how to define a class which can be used by those three JSON string deserialize to object?
Assuming that these three are your only possible JSON strings, you need to create three root classes. You can do this using some tools or simply by copying each of your JSON strings and pasting them by going to Edit > Paste Special > Paste JSON As Classes in Visual Studio. For instance the classes corresponding to jsonstring2 will look like this:
public class Rootobject
{
public Person[] data { get; set; }
}
public class Person
{
public string name { get; set; }
public string address { get; set; }
}
Then you need to detect the type of "data" like follows:
JObject jo = JObject.Parse(jsonstring2);
string type = jo["data"].GetType().Name;
which in this case will be JArray (the other two are JValue and JObject). Then you can deserialize the string to the correct class by using a switch statement.
Related
I need to bind a collection of objects from a querystring, but I cannot find the proper querystring format.
My controller code:
public class Filter
{
public string Name { get; set; }
public string Operator { get; set; }
public object Value { get; set; }
}
public void Get(IEnumerable<Filter> filters)
{
....
}
If you do want to pass the objects with querystring you could try as below:
https://localhost:44389/Test/Index?filters[0].Name=n1&filters[1].Name=n2&filters[2].Name=n3&filters[2].Value=v3
The result:
the offcial document related:
https://learn.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-6.0#collections
but i don't think it's a good solution,because the length of Url is limited,if your model has plenty properties and your collection has many elements ,you may get some error
Is it possible to do mapping during the deserialization process of a JSON string to an object?
var resultObject = JsonConvert.DeserializeObject<ConfigItemGetResult>(result);
My JSON string is different from the object I want to deserialize to. So mapping has to happen. I'm trying to avoid making a model that maps 1 to 1 to the JSON string followed by mapping from object to object with for example AutoMapper.
Use Serialization Attributes for configuring your serialization mapping
public class JsonTest
{
[JsonProperty(PropertyName = "SomePropNameFromJson")]
public string SomeProp { get; set; }
[JsonProperty(PropertyName = "SomeNested")]
public SomeClass SomeClass { get; set; }
}
public class SomeClass
{
public SomeClass1 SomeClass1 { get; set; }
}
public class SomeClass1
{
public string text { get; set }
}
Here Json
{ "SomeProp":"value", "SomeNested":{
"SomeClass1":{
"text":"textvalue"
}
} }
Json convert trying to convert text to object by prop name with value via reflection if them finds prop name in text they take value if prop name has different name in JSON you can specify it via [JsonProperty(PropertyName = "SomeNested")] if this attr not set by default it will try get by prop name and it whatever what property is, it some object(your nested objects) or basic type, it will trying to convert it automaticaly.
Current code in model:
[Display(Name = "E-mail")]
public string EMail { get; set; }
Desired code:
public string EMail { get; set; }
I would like to delegate the translation to a handler, something like this:
if(propertyName == "EMail") return "E-mail"
Based on my understanding of your question, I'm assuming that you are trying to implement localisation in your application.
If so, there are two options;
Resources
In .NET you can add Resource (.resx) files into your application to handle translation (one resx for each language). Then you can specify the Resource by specifying the ResourceType property of your Display attribute. For example;
public class Model
{
[Display(Name = "Email", ResourceType = typeof(Resources.Strings))]
public string Email { get; set; }
}
Custom attribute
Alternatively, if you are set on implementing this in a handler then you could implement a custom attribute, as demonstrated in this question.
Edit: Modified from the example in the above post.
If you add a new Resource file to your project - say Strings.resx and add "HelloWorld" as a field. You can then create a new attribute, such as LocalisedDisplayNameAttribute;
public class LocalisedDisplayNameAttribute : DisplayNameAttribute
{
public LocalisedDisplayNameAttribute(string resourceId)
: base(GetMessageFromResource(resourceId))
{
}
private static string GetMessageFromResource(string resourceId)
{
// "Strings" is the name of your resource file.
ResourceManager resourceManager = Strings.ResourceManager;
return resourceManager.GetString(resourceId);
}
}
You can then use it as follows;
public class Model
{
[LocalisedDisplayName("HelloWorld")]
public string Email { get; set; }
}
Let me know if I can help further,
Matt
I have a class:
public class ClientInformation{
public string UserName {get; set;}
public ICollection<RegionDistrictCity> RegionDistrictCity
{
get;
set;
}
public class RegionDistrictCity
{
public string Region { get; set; }
public string District { get; set; }
public string City { get; set; }
}
}
How should be formated the name attribute of input elements for properties Region, Distirct, City in html in order to make model binder populate collection "ICollection RegionDistrictCity"?
I tried to have an action method with parameter of type "ClientInformation" and html name attributes formated like "[index].PropertyName" but in that case only the property "UserName" is binded.
I tried to have action method with parameter name "client" and have html names attributes formated like "client[index].PropertyName" but it doesn't work. (in tha case if I there is a "List client" then it would get populated)
Thanks.
In MVC4 you should use a for loop instead of a foreach to bind your collection. Then the model binder will be able to populate your model when you submit your data.
#for (int i = 0; i < Model.RegionDistrictCity.Count; i++)
{
#Html.EditorFor(model => Model.RegionDistrictCity[i].Region)
}
But this will only work if you are not deleting or adding items to your collection dynamically.
If you want to do that, you should use the BeginCollectionItem helper created by steve sanderson. http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/
I have a simple Poco
public virtual short UserID
{
get;
set;
}
[Required]
public virtual string UserName
{
get;
set;
}
public virtual string Password
{
get;
set;
}
public virtual string Email
{
get;
set;
}
Im currently Using Dapper ORM.
Does anyone have a good example of how I would query using dapper ORM to create a drop-down-list?
The query should return Key=UserID and Value=UserName in a list so that I can retrieve the keys and populate the DropDownList.
you can create a class representing the pair:
class SelectItem
{
public long Key {get;set;}
public string Value {get;set;}
}
var list = connection.Query<SelectItem>(" select id Key UserName Value from yourtable",null).ToList();
you use the aliases to map the table fields to the class properties names. I'm supposing your table field names are id and UserName, change them according to your case.
You should also pay attention to the property types, you can have a bad cast exception if they don't match.
ALternatively, you can use the dynamic version:
var list = connection.Query(" select id Key UserName Value from yourtable",null).ToList();
you obtain a list of dynamics each with property named Key and UserName.