How to attach jstree nodes in form using jquery and receive in MVC Model? - c#

I have a form with multiple Jstree elements. I gathered all jstree nodes using this code:
var treeData = $('.jstree').jstree(true).get_json('#', { flat: false });
var jsonData = JSON.stringify(treeData);
result is an array of objects. each node has an array of children too.
in server-side I have a model like this:
public class SampleModel
{
public int Id { get; set; }
public string Name { get; set; }
public List<JsTreeNode> Products { get; set; }
}
and JsTreeNode is like this:
public class JsTreeNode
{
public string id { set; get; }
public string text { set; get; }
public string icon { set; get; }
public JsTreeNodeState state { set; get; }
public List<JsTreeNode> children { set; get; }
public JsTreeNodeLiAttributes li_attr { set; get; }
public JsTreeNodeAAttributes a_attr { set; get; }
public string data { get; set; }
public JsTreeNode()
{
state = new JsTreeNodeState();
children = new List<JsTreeNode>();
li_attr = new JsTreeNodeLiAttributes();
a_attr = new JsTreeNodeAAttributes();
}
}
I tried to append jstree data(appending treeData , or jsonData ).
var formData = new FormData($("form").get(0));
formData.append('Products', treeData);
But nothing were received in server-side.
How can I get this tree structure in Server.

Related

How to serialize JSON from Form (multipart/form-data) to list?

When I try to post multipart/form-data with my file and JSON, then lists are empty in model, but Alias, WorkerName and File are correctly serialized.
[HttpPost]
[Route("add")]
[Consumes("multipart/form-data")]
public async Task<JobAddDto> Add([FromForm] JobInputInternalDto model)
{
var form = Request.Form;
//do stuff with model
}
In Request.Form those values are correctly sent:
How can I serialize data from form to lists in my model?
I have my JobInputInternalDto written as:
public class JobInputDto
{
public string Alias { get; set; } = string.Empty;
public string WorkerName { get; set; } = string.Empty;
public IEnumerable<ParameterDto> Parameters { get; set; } = new List<ParameterDto>();
public IEnumerable<WorkflowOptionsDto> Workflow { get; set; } = new List<WorkflowOptionsDto>();
}
public class JobInputInternalDto : JobInputDto
{
public IFormFile? Payload { get; set; } = null;
}
With ParameterDto as:
public class ParameterDto
{
public int Order { get; set; }
public string Name { get; set; } = string.Empty;
public string Value { get; set; } = string.Empty;
}
And WorkflowOptionsDto as:
public class WorkflowOptionsDto
{
public int Order { get; set; }
public string WorkerName { get; set; } = string.Empty;
public string? WorkerVersion { get; set; } = null;
public IEnumerable<ParameterDto> Parameters { get; set; } = Enumerable.Empty<ParameterDto>();
}
What i can guess by your Request.Form image is that you've sent the Parameters data with Json format like:
{ Order: 0, Name: "Test Name 0", Value: "Test Value 0" }
But since you're using
[Consumes("multipart/form-data")]
As such, C# expects the model to be form formatted, and therefore a list of objects should have the following format:
As you can see in the following image, using form format, C# is able to bind the data properly:

Can't deserialize an indexed name value pair child node C#

I'm running into an issue when I am trying to deserialize a webAPI GET call that returns a JSON object. The issue being one particular property is always null after being deserialized.
The JSON object looks like this:
{
"status":"OK",
"masterlist":{
"session":{
"session_id":intValue,
"session_name":"stringValue"
},
"0":{
"bill_id":intValue,
"number":"stringValue",
"change_hash":"stringValue",
"url":"stringValue",
"status_date":"dateValue",
"status":"stringValue",
"last_action_date":"dateValue",
"last_action":"stringValue",
"title":"stringValue",
"description":"stringValue"
},
"1":{
"bill_id":intValue,
"number":"stringValue",
"change_hash":"stringValue",
"url":"stringValue",
"status_date":"dateValue",
"status":"stringValue",
"last_action_date":"dateValue",
"last_action":"stringValue",
"title":"stringValue",
"description":"stringValue"
},
"2":{
"bill_id":intValue,
"number":"stringValue",
"change_hash":"stringValue",
"url":"stringValue",
"status_date":"dateValue",
"status":"stringValue",
"last_action_date":"dateValue",
"last_action":"stringValue",
"title":"stringValue",
"description":"stringValue"
}
}
}
As you can see the second property of masterlist isn't an array, that would make life too easy... But it looks more like a collection of name/value pairs. I have reviewed This post and the associated one listed within but they both pertain to if the name/value pair where at the root level where mine is not.
My method that I am using to deserialize is:
BillMaster billMasterList = new BillMaster();
using (HttpClient client = new HttpClient())
{
string json = Get("&op=getMasterList&state=TN");
billMasterList = JsonConvert.DeserializeObject<BillMaster>(json);
}
And the model classes the deserializer is binding to:
public class BillMaster
{
public string Status { get; set; }
public BillMasterList masterlist { get; set; }
}
public class BillMasterList
{
public BillMasterList_Session session { get; set; }
public Dictionary<int, BillMasterList_Array> BillMasterList_Array { get; set; }
}
public class BillMasterList_Array
{
public int bill_id { get; set; }
public string number { get; set; }
public string change_hash { get; set; }
public string url { get; set; }
public string status_date { get; set; }
public string status { get; set; }
public string last_action_date { get; set; }
public string last_action { get; set; }
public string title { get; set; }
public string description { get; set; }
}
When I run the code I don't throw any errors and I have values in my object except for BillMasterList_Array, that is always null. I'm obviously not doing something right but what it is alludes me.

How to populate list as class object?

How do you populate a list as a class object? For example, this does not work:
[DataContract]
public class JsonReviewFormFields
{
[DataMember]
public PersonalDevelopmentPlan personalDevelopmentPlan { get; set; }
}
public class PersonalDevelopmentPlan
{
public List<ShortTerm> shortTerm { get; set; }
public List<LongTerm> longTerm { get; set; }
}
public class ShortTerm
{
public string workRelated { get; set; }
public string structured { get; set; }
public string informal { get; set; }
public string reviewDate { get; set; }
}
public class LongTerm
{
public string workRelated { get; set; }
public string structured { get; set; }
public string informal { get; set; }
public string reviewDate { get; set; }
}
This is controller action:
public JsonReviewFormFields GetReviewForm()
{
PersonalDevelopmentPlan personalDevelopmentPlan = new PersonalDevelopmentPlan();
List<ShortTerm> _itemsShort = new List<ShortTerm>();
_itemsShort.Add(new ShortTerm { workRelated = "workRelated text", structured = "structured text", informal = "informal text", reviewDate = "reviewDate" });
jsonReviewFormFields.personalDevelopmentPlan.shortTerm = _itemsShort;
List<LongTerm> _itemsLong = new List<LongTerm>();
_itemsLong.Add(new LongTerm { workRelated = "workRelated text", structured = "structured text", informal = "informal text", reviewDate = "reviewDate" });
jsonReviewFormFields.personalDevelopmentPlan.longTerm = _itemsLong;
return jsonReviewFormFields;
}
The code crashes at
jsonReviewFormFields.personalDevelopmentPlan.shortTerm = _itemsShort;
It's probably a basic object orientated error. How do you populate the list?
You are not instantiating it, you have to instantiated the type first:
jsonReviewFormFields.personalDevelopmentPlan = new PersonalDevelopmentPlan();
and then set property of it:
jsonReviewFormFields.personalDevelopmentPlan.shortTerm = _itemsShort
before that you also have to instantiate main class which i don't see in your controller action anywhere :
JsonReviewFormFields jsonReviewFormFields = new JsonReviewFormFields();

How to bind JSON response to Models in ASP MVC?

So I'm new to the ASP/.NET/C# game, so would definitely appreciate any help you might be able to offer me. I've currently got a Controller called "ProjectController.cs" that has an action "Index" which is supposed to pass a list of "projects" to the view. I've gone ahead and created the controller, the action, the API call and the view. However, per the screenshots provided - I am running into an error with the API call itself - I'm attempting to return a list of models to the controller to be passed to the view. I am doing this through by loading a JSON response from the http://10000ft.com api. Any ideas why I am continually getting jammed up when trying to create/validate new project objects against the model?
ProjectController.cs:
namespace MVCProject1.Controllers
{
public class ProjectController : Controller
{
// GET: Project
public ActionResult Index()
{
List<Models.Project> projects = APICalls.GetAllProjects();
return View(projects);
}
}
}
Project Controller / Index Action View:
#{
ViewBag.Title = "Project Index";
}
#model IEnumerable<MVCProject1.Models.Project>
#foreach (var project in Model)
{
#project.name <br />
}
ProjectModel.cs:
namespace MVCProject1.Models
{
public class Project
{
public int id { get; set; }
public bool archived { get; set; }
public object archived_at { get; set; }
public string description { get; set; }
public string guid { get; set; }
public string name { get; set; }
public object parent_id { get; set; }
public object phase_name { get; set; }
public string project_code { get; set; }
public string secureurl { get; set; }
public string secureurl_expiration { get; set; }
public int settings { get; set; }
public int timeentry_lockout { get; set; }
public string ends_at { get; set; }
public string starts_at { get; set; }
public object deleted_at { get; set; }
public string created_at { get; set; }
public string updated_at { get; set; }
public bool use_parent_bill_rates { get; set; }
public string thumbnail { get; set; }
public string type { get; set; }
public bool has_pending_updates { get; set; }
public string client { get; set; }
public string project_state { get; set; }
}
}
APICalls.cs:
namespace MVCProject1
{
public class APICalls
{
private const string baseUrl = "https://api.10000ft.com/api/v1/{0}?&auth=temp12345=&{1}";
#region PROJECTS
public static List<Models.Project> GetAllProjects()
{
string requestUrl = string.Format(baseUrl, "projects", "&per_page=200");
var resultString = RestClient.makeAPICall(requestUrl);
var resultObject = JsonConvert.DeserializeObject(resultString);
List<Models.Project> projects = new List<Models.Project>();
foreach (var project in resultObject.data)
{
projects.Add(project);
}
return projects;
}
#endregion
}
}
RESTClient.cs:
namespace MVCProject1
{
public static class RestClient
{
public static string makeAPICall(string requestUrl)
{
var syncClient = new WebClient();
var content = syncClient.DownloadString(requestUrl);
Trace.WriteLine(content.ToString());
return content;
}
}
}
Image of error I'm receiving
I think that you have an issue with deserialization of product list.
Try
var projects = JsonConvert.DeserializeObject<List<Models.Project>>(resultString);
instead of
var resultObject = JsonConvert.DeserializeObject(resultString);
List<Models.Project> projects = new List<Models.Project>();
foreach (var project in resultObject.data)
{
projects.Add(project);
}
and check that projects value is not null and no errors occures while deserialization

Serialize deserialize anonymous child JSON properties to model

I have an API I am receiving data from. That API is out of my control on how it is structured, and I need to serialize and deserialize the JSON output to map the data to my model.
Everything works well where JSON is nicely formatted with named properties.
What can you do where there is no named value and there is just an array of ints and strings? like under locations
here is a sample of the JSON:
{"id":"2160336","activation_date":"2013-08-01","expiration_date":"2013-08-29","title":"Practice Manager","locations":{"103":"Cambridge","107":"London"}}
I have models that are like:
public class ItemResults
{
public int Id { get; set; }
public DateTime Activation_Date { get; set; }
public DateTime Expiration_Date{ get; set; }
public string Title { get; set; }
public Location Locations { get; set; }
}
public class Location
{
public int Id { get; set; }
public string value { get; set; }
}
and I am mapping using the inbuilt ajax serialization:
protected T MapRawApiResponseTo<T>( string response )
{
if ( string.IsNullOrEmpty( response ) )
{
return default( T );
}
var serialize = new JavaScriptSerializer();
return serialize.Deserialize<T>( response );
}
var results = MapRawApiResponseTo<ItemResults>(rawApiResponse);
So the ID and all other properties are picked up and mapped but what every I do I can not seem to map the locations.
Many thanks
public Dictionary<int,string> Locations { get; set; }
job done; you should find that using Json.NET, at least, i.e.
var result = JsonConvert.DeserializeObject<ItemResults>(json);
you get 2 entries in result.Locations; specifically result[103] = "Cambridge"; and result[107] = "London";
If you don't mind, you can workaround with dictionary:
class Program
{
static void Main(string[] args)
{
string json =
"{'id':'2160336','activation_date':'2013-08-01','expiration_date':'2013-08-29','title':'Practice Manager','locations':{'103':'Cambridge','107':'London'}}";
var deserializeObject = JsonConvert.DeserializeObject<ItemResults>(json);
Console.WriteLine("{0}:{1}", deserializeObject.Locations.First().Key, deserializeObject.Locations.First().Value);
Console.ReadKey();
}
}
public class ItemResults
{
public int Id { get; set; }
public DateTime Activation_Date { get; set; }
public DateTime Expiration_Date { get; set; }
public string Title { get; set; }
public Dictionary<int, string> Locations { get; set; }
}
you can also use manual parsing, like here: Json.NET (Newtonsoft.Json) - Two 'properties' with same name?
This will work:
public Dictionary<string, string> Locations { get; set; }
public IEnumerable<Location> LocationObjects { get { return Locations
.Select(x => new Location { Id = int.Parse(x.Key), value = x.Value }); } }
I propose you the following solution :
public class ItemResults
{
public int Id { get; set; }
public DateTime Activation_Date { get; set; }
public DateTime Expiration_Date { get; set; }
public string Title { get; set; }
[JsonProperty("locations")]
public JObject JsonLocations { get; set; }
[JsonIgnore]
public List<Location> Locations { get; set; }
[OnDeserialized]
public void OnDeserializedMethod(StreamingContext context)
{
this.Locations = new List<Location>();
foreach (KeyValuePair<string, JToken> item in this.JsonLocations)
{
this.Locations.Add(new Location() { Id = int.Parse(item.Key), value = item.Value.ToString() });
}
}
}
public class Location
{
public int Id { get; set; }
public string value { get; set; }
}
After you just have to deserialize your JSON with : JsonConvert.DeserializeObject<ItemResults>(json);

Categories

Resources