How to get Data from Model to JavaScript MVC 4? - javascript

that's my function:
<script> function Calculate()
{
var ItemPrice = document.getElementById("price");
var weight = document.getElementById("weight");
var SelWeight = weight.options[weight.selectedIndex].value;
alert(SelWeight);
var Category = document.getElementById("SelectedCategory");
var SelCategory = Category.options[Category.selectedIndex].value;
alert(SelCategory);
}
</script>
i want to get SelCategories.Tax and SelCategories.Duty to add them to weight value and total price to show the total in a label.. I'm using ASP.NET MVC 4 and this is my Model that i want to use
public class CategoriesModel
{
public int CategoryID { get; set; }
public string CategoryName { get; set; }
public decimal Duty { get; set; }
public decimal Tax { get; set; }
public IEnumerable<SelectListItem> CategoriesList { get; set; }
}

I think the best approach here is to use Json and something like Vue.js, Knockout.js, etc. (but also you can do it without these libraries, if your case is simple).
First, you need to install Json support with a command in PM console:
PM> install-package NewtonSoft.Json
Then, in your view you can convert your model to javascript object like this:
#model ...
#using Newtonsoft.Json
...
<script type="text/javascript">
var data = #Html.Raw(JsonConvert.SerializeObject(this.Model));
</script>
Then you can access all the properties in your model with in plain JavaScript:
var id = data.CategoryID;
That's it! Use knockout (update 2018: this is obsolete, there is no reason you should use knockout now) if your logic is complicated and you want to make your view more powerful. It could be a little bit confusing for newbie, but when you get it, you'll gain the super-powerful knowledge and will be able to simplify your view code significantly.

You need to create actions (methods in the controller) that return JsonResult.
From the client side, make ajax calls to the server to recover and use that data. The easiest way to do this is to use any of the jQuery ajax methods.
public JsonResult GetData(int id)
{
// This returned data is a sample. You should get it using some logic
// This can be an object or an anonymous object like this:
var returnedData = new
{
id,
age = 23,
name = "John Smith"
};
return Json(returnedData, JsonRequestBehavior.AllowGet);
}
When you use a jQuery get to the /ControllerName/GetData/id, you'll get a JavaScript object in the success callback that can be used in the browser. This JavaScript object will have exactly the same properties that you defined in the server side.
For example:
function getAjaxData(id) {
var data = { id: id };
$.get('/Extras/GetData/1', // url
data, // parameters for action
function (response) { // success callback
// response has the same properties as the server returnedObject
alert(JSON.stringify(response));
},
'json' // dataType
);
}
Of course, in the success callback, instead of making an alert, just use the response object, for example
if (response.age < 18) { ... };
Note that the age property defined in the server can be used in the JavaScript response.

If you prefer a class try jsmodel. After converting the mvc view model to javascript it adds the benefit of retrieving DOM updates.
var jsmodel = new JSModel(#Html.Raw(Json.Encode(Model)));
Then anytime you want to get the latest state of the DOM do this to update your variable:
var model = jsmodel.refresh();
Website:
http://chadkuehn.com/jquery-viewmodel-object-with-current-values/
There is also a nuget:
https://www.nuget.org/packages/jsmodel/

var errors = '#Html.Raw(Json.Encode(ViewData.ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage)))';
var errorMessage=JSON.parse(errors);

Related

Pass array values from JavaScript to my MVC C# application

I would like to pass array values from javascript to my C#.
Currently I am getting GUID null in C#. Not sure where I am doing wrong.
When I check developer tool, I have values
http://localhost/mvc/CheckData?GUID[]=C71F952E-ED74-4138-8061-4B50B9EF6463&ColumnVal=1&RowVal=1
I would like to receive this GUID value in my C# code.
JavaScript
function CheckData(obj) {
$.ajax({
data: {GUID:eArray, ColumnVal: $('#DisColumn').val(), RowVal: $('#DisRow').val()},
url: "/mvc/CheckData",
cache: false,
success: function (result) {
....
}
});
}
C# backend code to receive values from front-end.
public ActionResult CheckData()
{
var GUID = HttpContext.Request["GUID"];
int columnVal = Convert.ToInt32(HttpContext.Request["ColumnVal"]);
int rowVal = Convert.ToInt32(HttpContext.Request["RowVal"]);
string result = (Services.CheckDataRecords(rowVal, columnVal,GUID)) ? "true" : "false";
return Content(result);
}
Currently, I am getting null when it hits to C# method var GUID = HttpContext.Request["GUID"];.
I can see array value in front-end. But it is somehow not passing that value.
HttpContext.Request represents the request, and to access query data, you will need to do something like this: HttpContext.Request.Query["GUID"].
A more straightforward approach is to let ASP.NET do the work for you is just turn your C# backend to this:
[HttpGet("CheckData")] //change the route based on your code
public ActionResult CheckData([FromQuery] Guid[] guid, int columnVal, int rowVal)
{
var GUIDs = guid;
int column = columnVal;
int row = rowVal;
.....//your code
}

Retrieving multiple values from C# to JavaScript

So I have an a tag with an onclick:
<a onclick="join(4);">Join</a>
Now when the a tag is clicked, it calls this code in this order:
JavaScript function:
function join(gymID) {
PageMethods.getGymInformation(gymID);
}
C# method:
[WebMethod]
public gymData getGymInformation(string gymID)
{
gyms gym = new gyms();
DataTable dt = gym.getNewGymInfo(System.Convert.ToInt32(gymID));
DataRow dr = dt.Rows[0];
return new gymData { name = dr["name"].ToString(), strength = dr["strength"].ToString(), speed = dr["speed"].ToString(), defence = dr["defence"].ToString()};
}
public DataTable getNewGymInfo(int gymID)
{
// This returns a datatable with 1 row
return gymTableApapter.getNewGymInfo(gymID);
}
[Serializable]
public sealed class gymData
{
public string name { get; set; }
public string strength { get; set; }
public string speed { get; set; }
public string defence { get; set; }
}
As you can see, the JavaScript join function calls the C# method which then retrieves a DataTable with 1 row, then using a custom data type it populates the strings with data to be returned..
Now I'm trying to figure out how to get the information returned from the C# method to be extracted in the JavaScript join function?
Is their a way to do this?
Add success/error callbacks in your JavaScript code. It might look something like this:
PageMethods.getGymInformation(gymID, onSuccess, onError);
function onSuccess (result) {
// result contains the returned value of the method
}
function onError (result) {
// result contains information about the error
}
Then in the onSuccess function you would have the returned value of the server-side method (of type gymData) in the result variable. At that point you can do whatever you need to do with it in your client-side code.
If the functions don't have any applicable re-use, you can even just add them in-line:
PageMethods.getGymInformation(gymID,
function (result) {
// success
}, function (result) {
// error
});

ASP.NET MVC - How to "reverse" model binding to convert a C# model back to a query string representation

I have a custom javascript on the client side that I use to build up a querystring and pass over to my asp.net-mvc controller
var templateQueryString = BuildTemplate();
$.ajax({
url: '/MyController/Save?' + templateQueryString,
type: 'post',
dataType: 'json',
success: function (data) {
}
}
and on my controller all of the properties leverage the model binding so it comes in as a single object on the server side. NOTE: that this is a pretty complex object with arrays and arrays of sub objects:
public ActionResult Save(MyTemplate template)
{
}
the issue now is that I need to be able to convert from my C# object back to a string that represents "myTemplateQueryString" on the client side.
Is there any recommended way to take an object and do the "reverse" model binding. They key here is that it generates a string that I could use as a query string again in the future to pass into another asp.ent-mvc controller action.
Here is an example of the querystring that I am storing locally:
<input type="hidden" value="showIds=false&showRisks=false&
amp;statusIds=2&statusIds=1&statusIds=6&statusIds=8&
amp;statusIds=3&statusIds=9&showCompleted=0"
name="filterQueryString" id="filterQueryString">
As #haim770 said it would be easier if you used JSON in the request payload, and not the query string to pass your complex object to the server.
Regarding creating the query string from a model there is not a built-in method that does something like that or any recommended approach as far as i know. An obvious solution is to use reflection and build the query string from your properties.
Assuming your BuildTemplate class looks something like:
public class BuildTemplate
{
public bool ShowIds { get; set; }
public bool ShowRisks { get; set; }
public bool ShowCompleted { get; set; }
public int[] StatusIds { get; set; }
}
You can develop an extension method to convert any object to a QueryString. Here is some initial code you can start with:
public static class ObjectExtensions
{
public static string ToQueryString(this Object obj)
{
var keyPairs = obj.GetType().GetProperties().Select(p =>
new KeyValuePair<string, object>(p.Name.ToLower(), p.GetValue(obj, null)));
var arr = new List<string>();
foreach (var item in keyPairs)
{
if (item.Value is IEnumerable && !(item.Value is String))
{
foreach (var arrayItem in (item.Value as IEnumerable))
{
arr.Add(String.Format("{0}={1}", item.Key, arrayItem.ToString().ToLower()));
}
}
else
arr.Add(String.Format("{0}={1}", item.Key, item.Value.ToString().ToLower()));
}
return "?" + String.Join("&", arr);
}
}
Then you can easily invoke this code on any object to generate a query string:
var person = new BuildTemplate() { StatusIds = new []{ 1, 5, 8, 9 }, ShowRisks = true };
var queryString = person.ToQueryString();
This would generate a query string like:
"?showids=false&showrisks=true&showcompleted=false&statusids=1&statusids=5&statusids=8&statusids=9"
This query string should work just fine with the default model binder for the BuildTemplate class.

using viewbag data with jquery json

I want to use my ViewBag in JavaScript array. I follow using viewbag with jquery asp.net mvc 3, and I think the following code is what I am looking for,
#model MyViewModel
<script type="text/javascript">
var model = #Html.Raw(Json.Encode(Model));
// at this stage model is a javascript variable containing
// your server side view model so you could manipulate it as you wish
if(model.IsLocal)
{
alert("hello " + model.FirstName);
}
</script>
But this code causes error for Json.Encode, then I add System.Runtime.Serialization.Json, but It also cause error for Encode, says no method for Encode, I already include Newtonsoft.Json, but still no result.
My ViewBag data ::
public ActionResult Dashboard()
{
ViewBag.inc = (from inc in db.Incident select inc.Title).ToList();
return View();
}
And I want to use this ViewBag.inc data in JavaScript array
As you said, you are already referencing the Newtonsoft Json.Net library, you can use this following code::
var inc = '#Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(ViewBag.inc))';
inc= JSON.parse(inc);
$.each(inc, function(index, data) {
//you next code
});
The snippet you are using does not use the ViewBag, but the Model. Regardless, if you want to print the serialisation of an object to the view, and you are already referencing the Newtonsoft Json.Net library (as you said you are), then you can do the following:
var model = #Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model));
If you want to use the item in the ViewBag instead, you can do:
var model = #Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(ViewBag.inc));
You can use like for ViewBag -
var mn = #{#Html.Raw(Json.Encode(ViewBag.ViewBagProperty));}
alert(mn.YourModelProperty);
And for Model -
var mn = #{#Html.Raw(Json.Encode(Model));}
alert(mn.YourModelProperty);
There is no need for NewtonSoft.Json, we can use default System.Web.Helpers.Json.
Update: Here goes the complete solution with Model, the same concept can be used with ViewBag too -
Lets say you have this Model -
public class XhrViewModel
{
public string data1 { get; set; }
public string data2 { get; set; }
}
Then in the controller action you are constructing the List of above Model in following way -
public ActionResult GetData()
{
List<XhrViewModel> model = new List<XhrViewModel>();
model.Add(new XhrViewModel() { data1 = "Rami", data2 = "Ramilu" });
return View(model);
}
Then on the View, you can have something like this -
#model IEnumerable<Rami.Vemula.Dev.Mvc.Controllers.XhrViewModel>
#{
ViewBag.Title = "GetData";
}
<h2>GetData</h2>
<script type="text/javascript">
var mn = #{#Html.Raw(Json.Encode(Model));}
alert(mn[0].data1);
</script>
And when you execute the page -

How to call asmx webservice for collection using BackboneJs

I hope someone could put me through a code to learn to call asmx webservices from backbone collection. The example i have put here is extremely simple
Collection
window["Persons"] = Backbone.Collection.extend({
model: Person,
url: "service.asmx/GetPeople"
});
note: I do have a service.asmx file at the point
Asmx End point
[WebMethod]
[ScriptMethod]
public static List<Person> GetPeople()
{
List<Person> people = new List<Person>(10);
for (int i = 0; i < 10; i++)
{
people.Add(new Person(i.ToString()));
}
return people;
}
The Model
public class Person
{
public string Name { get; set; }
public Person(string name)
{
Name = name;
}
}
when i do the below chrome xhr inspector informs me of this error
var family = new Persons();family.fetch();
Request format is unrecognized for URL unexpectedly ending in
'/GetPeople'
You will want to override the Backbone.sync() function to customize the persistence and retrieval of models from the server.
You can take a look at the annotated source code of how the Backbone.sync() function is overwritten for a local storage alternative.

Categories

Resources