Json to List<object> not binding - asp.net-mvc

I have a problem with object send in json format, that is not binded in Action Controller
Here the json parts:
function filterTxAjustement(arrTx) {
return {
dateDebut: $("#TxAjustementDateDebut").val(),
dateFin: $("#TxAjustementDateFin").val(),
ufCode: $("#TxAjustementUf").val(),
tx: JSON.stringify(arrTx)
};
}
function SaveTx() {
var arrTx = [];
$.each(Day, function (i, v) {
var $this = $('#' + v + 'Tx');
var tx = new Object();
tx.Day = v;
tx.Nb = parseInt($this.val());
tx.UfCode = parseInt($('#TxAjustementUf').val());
tx.Total = 0;
arrTx.push(tx);
});
$.ajax({
url: EasilyRelativeUrl("Lit/SetTxAjustementByDateAndUf"),
data: filterTxAjustement(arrTx),
type: 'POST',
dataType: 'json'
}).done(function (data) {
$('#TxAjustementGrid').data("kendoGrid").dataSource.read();
});
}
My array is well populated:
dateDebut:16/12/2013
dateFin:22/12/2013
ufCode:21124
tx:[{"Day":"Sunday","Nb":1,"UfCode":21124,"Total":0},{"Day":"Monday","Nb":2,"UfCode":21124,"Total":0},{"Day":"Tuesday","Nb":3,"UfCode":21124,"Total":0},{"Day":"Wednesday","Nb":0,"UfCode":21124,"Total":0},{"Day":"Thursday","Nb":0,"UfCode":21124,"Total":0},{"Day":"Friday","Nb":0,"UfCode":21124,"Total":0},{"Day":"Saturday","Nb":0,"UfCode":21124,"Total":0}]
But when it hit Action Controller, tx is null
public ActionResult SetTxAjustementByDateAndUf(DateTime dateDebut, DateTime dateFin, string ufCode, List<TauxAjustement> tx)
(Here the TauxAjustement object)
public class TauxAjustement
{
public string Day { get; set; }
public int Nb { get; set; }
public int Total { get; set; }
public int UfCode { get; set; }
}
I have tried with TauxAjustement[], but same issue. I have added Total = 0 and parseInt to have exact definition of C# object, but same...
What have I missed ? I do make a CustomBinderModel for this ?
Thanks for your help.

You need to define the tx argument as an array rather than a List:
public ActionResult SetTxAjustementByDateAndUf(DateTime dateDebut,
DateTime dateFin,
string ufCode,
TauxAjustement[] tx)
{}

Related

How to post json object with multiple values to the Controller from Ajax

I have this Ajax post working for a single value but I need it to work with multiple values. What am I missing?
I have already tried to make the public class 'Value' a List AND Guid[]. I have tried to adjust the method parameter to List AND Value[]. Not sure what else to try.
Class:
public class Value
{
public Guid TimeId { get; set; }
}
Method:
public IActionResult ApproveAllTimesheets([FromBody]Value information)
View JS:
function SubAll() {
var selectedValues = $('#timesheet').DataTable().column(0).checkboxes.selected().toArray();
var instructions = {};
for (var TimeId in selectedValues) {
instructions[TimeId] = { TimeId: selectedValues[TimeId] };
}
var inst = JSON.stringify(instructions);
$.ajax({
url: "/Admin/ApproveAllTimesheets",
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: inst,
success: function (result) {
alert(result);
},
error: function (xhr, textStatus) {
if (xhr.status == 401) { alert("Session Expired!"); window.location = "/Account"; }
else {
alert('Content load failed!', "info");
}
}
});
};
If I send through this object it works but I need to send through multiple values like my ajax post will do.
var instructions = { TimeId: "13246578-1234-7894-4562-456789123456" };
UPDATE #1
I found a structure that works for me by extending the class, now I just need to figure out how to create the correct object and array combination.
New Classes:
public class ValueContainer
{
public List<Value> MasterIds { get; set; }
}
public class Value
{
public Guid TimeId { get; set; }
}
Method:
public IActionResult ApproveAllTimesheets([FromBody]ValueContainer information)
Structure I need now (this works hard coded):
var jsonObject = {
"MasterIds": [{ TimeId: "13246578-1234-7894-4562-456789123450" }, { TimeId: "13246578-1234-7894-4562-456789123451" }, { TimeId: "13246578-1234-7894-4562-456789123452" }]
};
I'm still new to this stuff but what I see is that jsonObject is an object with a Key 'MasterIds' and the corresponding values are an array of objects with the key 'TimeId'...is this a correct evaluation?...and how to create it in code please?
You neec to create an array of objects and then set it in the container object :
var instructions = []; // an array
for (var i = 0; i < selectedValues.length; i++) {
instructions.push({ TimeId: selectedValues[i] };
}
var Value = {TimeId: instructions}; // creating object with property TimeId as array of guid
var inst = JSON.stringify(Value);
.......
....... your ajax code
and your class property should also be of type array:
public Guid[] TimeId { get; set; }

Jquery post to mvc 4 controller not passing data

I'm trying to pass data from JQuery to an MVC 4 controller. The controller gets invoked, but no data is passed. In the past I always just used form serialization, but that's not appropriate here.
My Controller:
[HttpPost]
public ActionResult Write(VideoSessionEnvelope envelope)
{
if (ModelState.IsValid)
{
envelope = Log.Write(envelope);
}
var result = Json(envelope);
return result;
}
We use an envelope class as a container for all view models
public class VideoSessionEnvelope : BaseEnvelope
{
public VideoSessionEnvelope()
{
SessionStart = new VideoSessionStartViewModel();
}
public Guid? LogEntryID { get; set; }
public VideoSessionStartViewModel SessionStart { get; set; }
}
}
The view model
public class VideoSessionStartViewModel: IViewModel
{
public string SessionId { get; set; }
public int UserId { get; set; }
public string Message { get; set; }
}
And finally the javascript
var Logging = Logging || {};
Logging.VideoSession = function () {
var Start = function (sessionId, userId, message) {
var envelope = {
SessionStart: {
"SessionId": sessionId,
"UserId": userId,
"Message": message
}
}
var data = JSON.stringify(envelope);
$.ajax({
type: "POST",
url: "/Logging/Write",
data: data,
datatype: "application/json",
success: function (result) {
return result;
},
error: function (request, status, error) {
return error;
}
});
};
return {
Start: Start
};
}();
According to Firebug the data is passed as
JSON
SessionStart Object { SessionId="sessionIdVal", UserId=123, Message="messageValue"}
Message "messageValue"
SessionId "sessionIdVal"
UserId 123
The controller gets called, but the properties in the view model are always null. I've tried several variations on the theme, nothing seems to work.
Try wrapping your data in a literal with the name as envelope so it will be picked up by the Model Binder:
data: { envelope: data },
UPDATE
Remove the call to JSON.stringify(), it is not strictly necessary to serialize the object literal.

Not Get data in jstree

I am create menu of Category and SubCategory in my project using jstree.
but i do not get or not show my data in jstree format.
so, what is problem.?
Plz Help me.
thnks....
My Controller Code
[HttpGet]
public JsonResult GetCatList()
{
IEnumerable<Category> cats = _CategoryBusiness.Select();
return new JsonResult
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = cats
};
}
My Model Class
[Serializable]
public class Category
{
[Key]
[DisplayName("Id")]
public int CategoryID { get; set; }
public string CategoryName { get; set; }
public int? SubCategoryID { get; set; }
[ForeignKey("SubCategoryID")]
public virtual Category SubCategory { get; set; }
}
And _CategoryBusiness.Select() is
public List<Category> Select(int id = 0)
{
var selectFrom = _Ctx.Categories.Select(a => a);
var query = selectFrom.Select(a => a);
if(id > 0)
query = query.Where(a => a.CategoryID == id);
return query.ToList();
}
And My View Page code is
<script type="text/javascript">
$(function () {
FillJSTree();
});
function FillJSTree() {
$("#onflycheckboxes").jstree({
json_data: {
"ajax": {
"url": "/Categories/GetCatList/",
"type": "GET",
"dataType": "json",
"contentType": "application/json charset=utf-8",
}
},
//checkbox: {
// real_checkboxes: true,
// checked_parent_open: true
//},
plugins: ["themes", "json_data", "ui"]
});
}
</script>
.
.
.
.
..
<div id="onflycheckboxes">
</div>
Try this: Before sending data to view, serialize that. This works for me. P.s. Your category data must be tree node.
[HttpGet]
public string GetCatList()
{
IEnumerable<Category> cats = _CategoryBusiness.Select();
string myjsonmodel = new JavaScriptSerializer().Serialize(cats);
return myjsonmodel;
}

uCommerce - add dynamic property to order line

I have hit a problem building a uCommerce site based on top of the demo razor store available http://thesitedoctor.co.uk/portfolio/avenue-clothingcom/
The demo uses servicestack and the ucommerceapi for its basket functions.
I am trying to add a dynamic property to the basket (on an order line) at the point where the user clicks buy. I traced through the productpage.js file and amended the code to add a new property ('message'):
function (data) {
var variant = data.Variant;
$.uCommerce.addToBasket(
{
sku: variant.Sku,
variantSku: variant.VariantSku,
quantity: qty,
message: $('#personalisedMessage').val()
},
function () {
updateCartTotals(addToCartButton);
}
);
});
using firebug, i checked the data that is being posted
addToExistingLine: true
message: "this is a message"
quantity:"1"
sku: "Product (options: none)"
variantSku:""
Posting this does not cause an error, but I cannot tell if it has worked either - I cannot find it in the database, assuming that it would be stored in OrderProperty table. In this scenario, I am 'buying' a product with no variations.
Any help is greatly appreciated with this.
Out of the box you can't add order/line item properties via the API like that. The API payload that you've added to is specified although valid JSON won't get interpreted/used by the API.
Instead what you'll need to do is add your own method to the API. To do this you'll need to implement a service from IUCommerceApiService and then you can do what you need. I've created an example (untested) below and will get it added to the demo store as I think it's a useful bit of functionality to have.
public class AddOrderLineProperty
{
public int? OrderLineId { get; set; }
public string Sku { get; set; }
public string VariantSku { get; set; }
public string Key { get; set; }
public string Value { get; set; }
}
public class AddOrderLinePropertyResponse : IHasResponseStatus
{
public AddOrderLinePropertyResponse() { }
public AddOrderLinePropertyResponse(UCommerce.EntitiesV2.OrderLine line)
{
if (line == null)
{
UpdatedLine = new LineItem();
return;
}
var currency = SiteContext.Current.CatalogContext.CurrentCatalog.PriceGroup.Currency;
var lineTotal = new Money(line.Total.Value, currency);
UpdatedLine = new LineItem()
{
OrderLineId = line.OrderLineId,
Quantity = line.Quantity,
Sku = line.Sku,
VariantSku = line.VariantSku,
Price = line.Price,
ProductName = line.ProductName,
Total = line.Total,
FormattedTotal = lineTotal.ToString(),
UnitDiscount = line.UnitDiscount,
VAT = line.VAT,
VATRate = line.VATRate
};
}
public ResponseStatus ResponseStatus { get; set; }
public LineItem UpdatedLine { get; set; }
}
public class AddOrderLinePropertyService : ServiceBase<AddOrderLineProperty>, IUCommerceApiService
{
protected override object Run(AddOrderLineProperty request)
{
var orderLineId = request.OrderLineId;
var sku = request.Sku;
var variantSku = request.VariantSku;
var orderLine = findOrderLine(orderLineId, sku, variantSku);
addPropertyToOrderLine(orderLine, request.Key, request.Value);
TransactionLibrary.ExecuteBasketPipeline();
var newLine = findOrderLine(orderLineId, sku, variantSku);
return new AddOrderLinePropertyResponse(newLine);
}
private void addPropertyToOrderLine(OrderLine orderLine, string key, string value)
{
if (orderLine == null)
return;
orderLine[key] = value;
orderLine.Save();
}
private static OrderLine findOrderLine(int? orderLineId, string sku, string variantSku)
{
return orderLineId.HasValue
? getOrderLineByOrderLineId(orderLineId)
: getOrderLineBySku(sku, variantSku);
}
private static OrderLine getOrderLineBySku(string sku, string variantSku)
{
return String.IsNullOrWhiteSpace(variantSku)
? getOrderLines().FirstOrDefault(l => (l.Sku == sku))
: getOrderLines().FirstOrDefault(l => (l.Sku == sku && l.VariantSku == variantSku));
}
private static OrderLine getOrderLineByOrderLineId(int? orderLineId)
{
return getOrderLines().FirstOrDefault(l => l.OrderLineId == orderLineId);
}
private static ICollection<OrderLine> getOrderLines()
{
return TransactionLibrary.GetBasket().PurchaseOrder.OrderLines;
}
}
You'll need to add the new method to uCommerce.jQuery.js as well something like this:
addOrderLineProperty: function (options, onSuccess, onError) {
var defaults = {
orderLineId: 0
};
var extendedOptions = $.extend(defaults, options);
callServiceStack({ AddOrderLineProperty: extendedOptions }, onSuccess, onError);
}
Let me know if you have any issues using it.
Tim

SingalR Mapping json object to c# object

Does SignlaR automatically map json object sent from to client to c# object? if so, what could i be doing wrong here?
C# Object
public class ChatHub :Hub
{
public void broadcastMessage(CommentModel model)
{
string test = model.Comment;
// Clients.All.writeMessage(jsonString);
}
public class CommentModel
{
[Required]
public string Name { get; set; }
[Required]
public string Comment { get; set; }
[Required]
public string EmailAddress { get; set; }
}
}
JavaScript
$(document).ready(function () {
var chat = $.connection.chatHub;
chat.client.writeMessage = function (t) {
var name = t.Name;
var email = t.Email;
var id = t.id;
var text = name + " " + email + " " + id + " ";
$("#test").append(text);
}
$("form").submit(function (e) {
var jsonObject = JSON.stringify($(this).serializeObject());
chat.server.broadcastMessage(jsonObject);
e.preventDefault();
});
$.connection.hub.start();
});
$.fn.serializeObject = function () {
var o = {};
var a = this.serializeArray();
$.each(a, function () {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
You seem to be sending a Json string to the app server whereas the server is expecting an object.
Change:
var jsonObject = JSON.stringify($(this).serializeObject());
To:
var jsonObject = $(this).serializeObject();

Resources