In my front end, I'm trying to call methods dynamically, but I keep getting errors of contexts.
My code looks like this and the error is given by my "i":
.aspx :
<script src="https://PCYULD0029:8012/Maps/leaflet.js"></script>
<script >
... some code
AllObject = "<%=(ParseMapObjects())%>";
L.marker([0, 0], 0).addTo(map).bindPopup("test");
for (var i = 0; i < 2; i++)
{
ObjLongitude = AllObject[i].Longitude;
ObjLatitue = AllObject[i].Latitude;
CreateMarkers(ObjLongitude, ObjLatitude)
L.marker([0, 0], 0).addTo(map).bindPopup("test");
L.marker([0, 50], 0).addTo(map).bindPopup(ObjLatitue);
}
function CreateMarkers(ObjLong, ObjLat) {
L.marker([ObjLong, ObjLat], 0).addTo(map).bindPopup("Test");
}
... some code
</script>
.aspx.cs :
public List<MapObjectEntity> ParseMapObjects()
{
List<MapObjectEntity> MapObjects = new List<MapObjectEntity>();
.... Some code
return MapObjects;
}
public class MapObjectEntity
{
// Properties
public Guid MapObjectGuid { get; set; }
public string Data { get; set; }
public int Latitude { get; set; }
public Guid Link { get; set; }
public int Longitude { get; set; }
public int RelativeHeight { get; set; }
public int RelativeWidth { get; set; }
public int Rotation { get; set; }
public bool ObjectShowFov { get; set; }
public Guid MapObjectType { get; set; }
}
So, in ParseMapObjects, I return a List of MapObjectEntity. I then try to catch that in my .aspx (frontend), so that I can use it as an object (ex: Object.property).
With the line AllObject = "<%=(ParseMapObjects())%>"; I succeed at pulling the object, but I can't seem to find a way to use AllObject to get my properties (ex: AllObject[0].Latitude).
My objective here is to loop through my AllObject and extract all the Latitude and Longitude values. But I can
thank you
Unless ParseMapObjects() returns a JSON string (something like caner's answer)
this won't work.
And bear in mind, once the page has loaded, this value will be fixed, since it's the result of the C# method that is output to the page, not a reference to the method. If you run the Javascript multiple times, the value assigned to AllObject on that line will stay fixed, because it's basically a static object in the JS context (check the View Source of your browser to see what is output).
You can't call a C# method directly from JavaScript, and vice versa. C# executes on the server and constructs the HTML, CSS and JS to output to the browser. JavaScript runs in the client's browser after the page (i.e. the content generated by the C#) has been downloaded from the server to the browser and initialised. They are in totally separate environments (usually on different computers) and intrinsically have no knowledge of each other. This separation is a vital concept to grasp if you want to develop web applications.
If you want communication between the client (browser) and the server outside of the normal page load / refresh / postback mechanism, then you need to use AJAX functionality, or even, if you want real-time communication, something like WebSockets and/or SignalR.
You need serialization...
public string ParseMapObjects()
{
List<MapObjectEntity> MapObjects = new List<MapObjectEntity>();
return new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(MapObjects);
}
and access in your script like
var AllObject = <%=(ParseMapObjects())%>;
Related
I am new to .net core - have been using aspx web pages and .net framework 4.x for a number of years. I have a project where we want to display different controls (textbox, dropdown, checkbox) on the page based on values returned from a query. For example, user chooses "A" from a dropdown list and it shows 10 controls, if they choose object B it shows 8 controls, etc. Previously in .net framework, I would use a content placeholder with an ID and then find that ID and start adding controls (controls.Add(newControl)) in the placeholder. It doesn't seem that is an option with .net core. It seems like this would be a common need for various web applications, but I'm not finding many hits.
Another question is whether this can be done in the code behind or if it has to be done on the client-side. If one of the controls in the list is a dropdown, there will be a query that a subroutine will run to get the Key/Value pairs for the dropdown. To me this means it would be more effective on the server side.
I haven't really found any good examples when I do some searching. Can anyone point me to a good resource or provide me with a basic example - either client-side or server-side? Thanks!
There are many options, but I'll describe a simple one, using server side processing. As you explained in your comment, there will be 2 pages:
One that will display the select element that will be used to choose a set of controls.
The page that will be returned according to the previous choise, displaying the selected set of controls.
I assume that you know how to build the first page.
For the second page, you can leverage the ASP.NET Core MVC pattern to achieve the desired result.
You will need the three usual MVC elements:
An Action in a Controler.
A ViewModel for your Razor View.
A Razor View.
The Action does the following:
Receives the id of the selected set of control (via the Action's parameter).
Uses this id to retrieve the information about the corresponding set of controls from your repository.
Builds a ViewModel out of the received information.
Builds a View using the obtained ViewModel.
Return the builded View.
Here is some simplified example code:
In your controller, add the following method:
#!lang-cs
Public IActionResult GetProgramControlSet(int ProgramId)
{
// Here, use the id to get the data from your repository
// that will be used to build set of controls.
// Supposing you have defined a GetControls method,
// it could look like:
var SelectedControls = MyRepository.GetControls(ProgramId);
// If needed, you can build a ViewModel out of the received SelectedControls.
var SelectedControlsViewModel = new ControlSetViewModel(SelectedControls);
return View(SelectedControlsViewModel)
}
Of course, many things are missing here: error handling, etc...
Here is what the ViewModel could be:
#!lang-cs
public class ControlSetViewModel
{
public string Name { get; private set; }
public List<IControl> Controls { get; private set; }
public ControlSetViewModel(...)
{
// Whatever needs to be done to construct the ViewModel
}
}
public enum ControlKind
{
Button,
Select,
Textarea
//...
}
public interface IControl
{
ControlKind Kind { get; }
}
public class ControlButton : IControl
{
public ControlKind Kind => ControlKind.Button;
public string Label { get; set; }
public string Text { get; set; }
public string Color { get; set; }
// ... All other needed properties for the button
}
public class ControlTextarea : IControl
{
public ControlKind Kind => ControlKind.Textarea;
public string Label { get; set; }
public string PlaceholderText { get; set; }
public string RowCount { get; set; }
// ... All other needed properties for the textarea
}
public class ControlSelect : IControl
{
public ControlKind Kind => ControlKind.Select;
public string Label { get; set; }
public string PlaceholderText { get; set; }
public List<SelectOption> Options { get; set; }
// ... All other needed properties for the select
}
public class SelectOption
{
public string Text { get; set; }
public string Value { get; set; }
}
You could also use inheritance instead of interface for the control classes.
Now the view.
It is a Razor page containing something akin to
#model ControlSetViewModel
#*... some HTML ...*#
<div>
<h1>#Model.Name</h1>
#foreach(var control in Model.Controls)
{
<div>
switch(control.GetControlKind())
{
case ControlKind.TextArea:
var Textarea = (ControlTextarea)control;
<label>#Textarea.Label</label>
<textarea rows="#Textarea.RowCount"/>
break;
case ControlKind.Select:
var Select = (ControlSelect)control;
<label>#Select.Label</label>
<select>
#foreach(var option in Select.Options)
{
<option value="#option.Value">#option.Text</option>
}
</select>
break;
#*... etc ...*#
default:
#*... etc ...*#
}
</div>
}
</div>
#*... More HTML ...*#
Of course this is far to be finished. All the infrastructure and code that will actually react to the displayed controls is missing.
Is it a form you that will be posted?
Is it Javascript code that will react to the control manipulation?
Or another mecanism?
This questions will need to be addressed.
I am working with an API that returns data in JSON format (as far as I can tell, this is my first time working with a true API or JSON). I read a bunch about working with JSON in C#, and eventually got the Newtonsoft.Json library. Unfortunately, I am having a hard time converting the response I am receiving into a C# class following the examples that exist in the Newtonsoft documentation.
Here is an example of the data returned by this API:
{"name":{"id":1,"name":"name","pID":1,"revisionDate":1390580000000}}
And heres what I have so far:
public class apiDataObject
{
public long id {get; set;}
public string name { get; set; }
public int pID { get; set; }
public long revisionDate { get; set; }
}
public long getID()
{
try
{
data = WebRequest.Create(baseURL);
retData = data.GetResponse().GetResponseStream();
}
catch (Exception exception)
{
outputBox.AppendText(Environment.NewLine + exception.ToString());
}
retDataReader = new StreamReader(retData);
returnedData = retDataReader.ReadToEnd();
outputBox.AppendText(returnedData);
apiDataObject test = new apiDataObject();
JsonConvert.PopulateObject(returnedData, test);
return test.id;
}
I have also tried replacing the JsonConvert.PopulateObject(returnedData, test) with:
apiDataObject test = JsonConvert.DeserializeObject<apiDataObject>(returnedData)
The problem is that my "test" object is always empty after the code finishes. I have stepped through the code, and everything works great until I get to the lines where the test object is created, and supposedly populated. I also tried the inbuilt Microsoft libraries and had the exact same issue. I am honestly stumped, I have spent 2 or 3 hours looking at these few lines of code and tons of documentation and samples of the Newtonsoft.Json library, but simply cant figure out where I've gone wrong here. Any help would be greatly appreciated.
From the JSON you posted, its actually a dictionary type: I changed your method to show you, I tested it out and it works.
public long GetID()
{
var testDict = new Dictionary<string, apiDataObject>();
var returnedData = "{\"name\":{\"id\":1,\"name\":\"name\",\"pID\":1,\"revisionDate\":1390580000000}}";
JsonConvert.PopulateObject(returnedData, testDict);
return testDict["name"].id;
}
Running your original code throws an exception telling you that it doesn't know what to do with the first "name".
Just in case anyone ever comes across this in a search, I figured out an alternative solution to working with this type of data as well. The Newtonsoft.Json library contains a function called DeserializeObject. So for the sample data of:
{"name":{"id":1,"name":"name","pID":1,"revisionDate":1390580000000}}
You can create an object that looks like:
public class Name
{
public int id { get; set; }
public string name { get; set; }
public int pID { get; set; }
public long revisionDate { get; set; }
}
public class RootObject
{
public Name name { get; set; }
}
and then use:
JsonConvert.DeserializeObject<RootObject>(returnedData);
to convert the json into the object without having to use a dictionary.
This is probably "common knowledge", considering the object code can easily be created using the json2csharp converter someone linked earlier, but I was unable to find any direct explanation about when to use the DeserializeObject function or why it should be used versus PopulateObject.
I have a view which has different sections displaying different type of orders from DB (SQL Server). Now I need to refresh view with updated information each time a new order is submitted through Android Application. Below are code snippets:
ViewModel:
public class KitchenViewModel
{
public List<Orders> DisplayOrders { get; set; }
public List<Orders> PreparedOrders { get; set; }
public List<OrderItem> ProgressItems { get; set; }
public List<OrderItem> QueuedItems { get; set; }
public int DisplayOrdCount { get; set; }
public int PreparedOrdCount { get; set; }
public int QueuedOrdCount { get; set; }
}
Controller:
public ActionResult KitchenOrder()
{
KitchenModel kitchenInstance = new KitchenModel();
List<Orders> orders = kitchenInstance.GetProgOrdersList();
List<OrderItem> progressItems = kitchenInstance.GetItemProgress();
List<OrderItem> queuedItems = kitchenInstance.GetItemQueued();
List<Orders> prepOrders = kitchenInstance.GetPrepOrdersList();
List<Orders> queuedOrders = kitchenInstance.GetQueuedOrdersList();
KitchenViewModel viewModel = new KitchenViewModel();
viewModel.PreparedOrders = prepOrders;
viewModel.ProgressItems = progressItems;
viewModel.DisplayOrders = orders;
viewModel.QueuedItems = queuedItems;
viewModel.DisplayOrdCount = orders.Count;
viewModel.PreparedOrdCount = prepOrders.Count;
viewModel.QueuedOrdCount = queuedOrders.Count;
return View(viewModel);
}
As of now I am auto refreshing view after every 15 seconds which is working perfectly.
But I need to refresh view only when a new order is submitted through Android application and order is inserted in DB. Once a new order is submitted the values for PreparedOrders, Progressitems, DisplayOrders gets changed and need to be fetched again. I have read many posts/tutorials relating to Observer pattern and publisher/subscriber method but unable to get crisp solution which would fit best. Could someone please provide relevant pointer/tutorial to use in such a scenario that could help. Being this my very first project and a total beginner, I m quite confused as in how to proceed.
So if you have to update site on event that fires when something changes in base, as other clients have changed it, you need PUSH based architecture, and not PULL based like you do it now (requests on timer elapsed).
For this purpose you can use SignalR, that implements various modern communication mechanisms. The basic idea is: one time client accessed your site, there is a persistent
connection created pointing to it's browser, and in the moment of notification you just roll over all available clients and notify them. On client side, naturally, event is handled in your case with javascript.
Worth mentioning that this technology has limitations across browser versioning, so refer to documentation to see if supported browser versions set satisfies your requirements.
Here is the link to supported platforms list for SignalR2: Supported platforms
I've been working with javascript Highcharts and I made a basic 'Chart Builder' app. One of my goals is to have the user create and modify as many options as they like and save those to the db. The main problem I'm having is trying to convert the Highcharts object to a c# class. I've been building it slowly(ie manually) with the parts I need, as I need them, but to eventually get the whole thing converted will take a long time.
Ideally, I'd like to create and setup the whole highcharts options object server side and just send it 100% complete to highcharts
Is there any easy way to do this? Has anyone already done this?
Here is the Highcharts reference page: http://www.highcharts.com/ref/
and this is what I've done so far.
public class Highchart
{
public title title { get; set; }
public plotOptions plotOptions { get; set; }
}
public class title
{
public string text { get; set; }
}
public class plotOptions
{
public series series { get; set; }
}
public class series
{
public string stacking { get; set; }
public string borderColor { get; set; }
public bool shadow { get; set; }
public int borderWidth { get; set; }
}
As you can see, I just started ^_^
Update : The Highcharts .Net library has been updated in December, and is nearly feature complete as per V2.1.9 of the Javascript library.
The .Net library currently has support for multiple axes, point objects, viewstate management after postbacks, click events for points, series etc, and a built in implementation of an AJAX datasource ;) You don't need to write a single line of JS code unless you want to handle click events; you simply code in C#, and the appropriate JS is rendered automatically for you..
Click here to view the Live Demo
I have a c# object (below) that I'm trying to send to my javascript.
My problem is, that while I can iterate over the items in the list, I can't get to the string-property ('Period').
Referencing the object in JS shows no property at all. After Json-encoding in c#, I can still see the property just before returning it to caller (hovering over the result variable in below function):
[OutputCache(Duration = 0, VaryByParam = "None")]
public JsonResult GetRankingList() {
Response.ContentType = "text/javascript";
var user = _userService.GetUserByPrincipal(User);
// Note, we do this while the user waits as we need to make progress in repeated calls to get the compared ranking list.
_businessLogicServiceMaintenance.PerformMaintenanceSteps();
//TODO: Replace with userid (Guid)
var rankingList = _presenterService.GetRankingListForDisplay(user);
if (rankingList == null)
return Json("");
var result = Json(rankingList);
return result;
}
How on earth can I get past this? Any comments appreciated!
Yours, Anders, Denmark,
public class RankingListForDisplay : List<RankingListLine>
{
public string Period { get; set; }
}
Thanks for taking your time - I found a solution.
I changed above implementation of RankingListForDisplay to the one below. For some reason json likes it way better ;-)
public class RankingListForDisplay
{
public List<RankingListLine> Lines { get; set; }
public string Period { get; set; }
public RankingListForDisplay()
{
Lines = new List<RankingListLine>();
Period = "<Unspecified>";
}
}