I just converted json to c# class using json2csharp.com. Then trying to pass that json from view to my controller but problem is only "create_time" object value is garbing successfully no any other value is able to grab. Also please check my debug picture to get better idea. What mistake it can be?
Json i am passing from view:
{"id":"WH-0G571461Y8752214W-8RU19841BY148894W","create_time":"2017-02-27T23:14:14Z","resource_type":"invoices","event_type":"INVOICING.INVOICE.CREATED","summary":"An invoice has been created","resource":{"id":"INV2-3RK5-HZV6-35UP-3LLU","number":"8035","template_id":"TEMP-6MT19746YC041742U","status":"DRAFT","merchant_info":{"email":"ppaas_default#paypal.com","first_name":"Dennis","last_name":"Doctor","business_name":"Medical Professionals, LLC","phone":{"country_code":"001","national_number":"5032141716"},"address":{"line1":"1234 Main St.","city":"Portland","state":"OR","postal_code":"97217","country_code":"US"}},"billing_info":[{"email":"example#example.com"}],"shipping_info":{"first_name":"Sally","last_name":"Patient","business_name":"Not applicable","phone":{"country_code":"001","national_number":"5039871234"},"address":{"line1":"1234 Broad St.","city":"Portland","state":"OR","postal_code":"97216","country_code":"US"}},"items":[{"name":"Sutures","quantity":100,"unit_price":{"currency":"USD","value":"5.00"}}],"invoice_date":"2017-02-27 PDT","payment_term":{"term_type":"NET_45","due_date":"2017-04-13 PDT"},"tax_calculated_after_discount":false,"tax_inclusive":false,"note":"Medical Invoice 27 Feb, 2017","total_amount":{"currency":"USD","value":"500.00"},"metadata":{"created_date":"2017-02-27 14:42:03 PDT"},"allow_tip":false,"links":[{"rel":"self","href":"https://api.paypal.com/v1/invoicing/invoices/INV2-3RK5-HZV6-35UP-3LLU","method":"GET"},{"rel":"send","href":"https://api.paypal.com/v1/invoicing/invoices/INV2-3RK5-HZV6-35UP-3LLU/send","method":"POST"},{"rel":"update","href":"https://api.paypal.com/v1/invoicing/invoices/INV2-3RK5-HZV6-35UP-3LLU/update","method":"PUT"},{"rel":"delete","href":"https://api.paypal.com/v1/invoicing/invoices/INV2-3RK5-HZV6-35UP-3LLU","method":"DELETE"}]},"links":[{"href":"https://api.paypal.com/v1/notifications/webhooks-events/WH-0G571461Y8752214W-8RU19841BY148894W","rel":"self","method":"GET","encType":"application/json"},{"href":"https://api.paypal.com/v1/notifications/webhooks-events/WH-0G571461Y8752214W-8RU19841BY148894W/resend","rel":"resend","method":"POST","encType":"application/json"}],"event_version":"1.0"}
Custom ViewModel:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace WebApplication2.WebhookModels.paypal
{
public class Phone
{
public string country_code { get; set; }
public string national_number { get; set; }
}
public class Address
{
public string line1 { get; set; }
public string city { get; set; }
public string state { get; set; }
public string postal_code { get; set; }
public string country_code { get; set; }
}
public class MerchantInfo
{
public string email { get; set; }
public string first_name { get; set; }
public string last_name { get; set; }
public string business_name { get; set; }
public Phone phone { get; set; }
public Address address { get; set; }
}
public class BillingInfo
{
public string email { get; set; }
}
public class Phone2
{
public string country_code { get; set; }
public string national_number { get; set; }
}
public class Address2
{
public string line1 { get; set; }
public string city { get; set; }
public string state { get; set; }
public string postal_code { get; set; }
public string country_code { get; set; }
}
public class ShippingInfo
{
public string first_name { get; set; }
public string last_name { get; set; }
public string business_name { get; set; }
public Phone2 phone { get; set; }
public Address2 address { get; set; }
}
public class UnitPrice
{
public string currency { get; set; }
public string value { get; set; }
}
public class Item
{
public string name { get; set; }
public int quantity { get; set; }
public UnitPrice unit_price { get; set; }
}
public class PaymentTerm
{
public string term_type { get; set; }
public string due_date { get; set; }
}
public class TotalAmount
{
public string currency { get; set; }
public string value { get; set; }
}
public class Metadata
{
public string created_date { get; set; }
}
public class Link
{
public string rel { get; set; }
public string href { get; set; }
public string method { get; set; }
}
public class Resource
{
public string id { get; set; }
public string number { get; set; }
public string template_id { get; set; }
public string status { get; set; }
public MerchantInfo merchant_info { get; set; }
public List<BillingInfo> billing_info { get; set; }
public ShippingInfo shipping_info { get; set; }
public List<Item> items { get; set; }
public string invoice_date { get; set; }
public PaymentTerm payment_term { get; set; }
public bool tax_calculated_after_discount { get; set; }
public bool tax_inclusive { get; set; }
public string note { get; set; }
public TotalAmount total_amount { get; set; }
public Metadata metadata { get; set; }
public bool allow_tip { get; set; }
public List<Link> links { get; set; }
}
public class Link2
{
public string href { get; set; }
public string rel { get; set; }
public string method { get; set; }
public string encType { get; set; }
}
public class RootObject
{
public string id { get; set; }
public DateTime create_time { get; set; }
public string resource_type { get; set; }
public string event_type { get; set; }
public string summary { get; set; }
public Resource resource { get; set; }
public List<Link2> links { get; set; }
public string event_version { get; set; }
}
}
Controller:
[HttpPost]
public ActionResult InvoicePaid(RootObject rootObject)
{
using (var ctx = new db_someEntities())
{
}
return Json("ok");
}
I'll assume you're on dotnet core (maybe on a migrated project?) because the code you're posting doesn't have any issues on previous versions of asp.net mvc.
If that's the case, it turns out that on dotnet core the model binding behaviour has changed a little compared to previous versions.
If you want the solution quickly just decorate the parameter of your POST action with [FromBody] attribute. It should work.
[HttpPost]
public ActionResult InvoicePaid([FromBody]RootObject rootObject)
{
using (var ctx = new db_someEntities())
{
}
return Json("ok");
}
The story is a little longer though, and very interesting by the way. If you want the details, I've not found any better resource than this post from Andrew Lock.
UPDATE
I can confirm that if you add the [FromBody] on the action, (I've tested using a bare new asp.net core 2. web app project) it binds the model correctly.
Please let me know if you want me to provide the sources I've used so you can troubleshot from there.
Hope this helps!
Most probably the data being sent it not formatted properly
From comments it was indicated that the data was being sent like
$.post(hookUrl, { testJson: testJson }).done(function (data) { console.log(data); });
consider formatting the data and including the content type
var data = JSON.stringify(testJson); //replace content with your JSObject
$.post(hookUrl, data, null, "application/json")
.done(function (data) { console.log(data); });
Or using the longer syntax
var data = JSON.stringify(testJson); //replace content with your JSObject
$.ajax({
type: "POST",
url: hookUrl,
data: data,
dataType: "application/json",
success: function (data) { console.log(data); }
});
You need to use [FromBody], so MVC knows where to look for the data.
[HttpPost]
public ActionResult InvoicePaid([FromBody]RootObject rootObject)
I've got this class in my Model:
public class GetDocParams {
public string LogonTicket { get; set; }
public int CliRid { get; set; }
public string[] ValPairs { get; set; }
public string SortBy { get; set; }
public int StartRec { get; set; }
public int EndRec { get; set; }
}
This is going to be used as input to a WebApi2 function to retrieve query results from Entity Framework.
The function takes the valPairs from input and uses it to build a query that sorts by the passed pairs, i.e.
CLI_RID=111111
DOC_NAME=Letter
would create the SQL:
WHERE CLI_RID = 111111
AND DOC_NAME = 'Letter'
I'm kind of curious, how would I pass the ValPairs, using ajax and/or WebClient?
GET or POST doesn't matter.
You may have to add a new class for ValPair, like the following.
public class GetDocParams {
public string LogonTicket { get; set; }
public int CliRid { get; set; }
public ValPair[] ValPairs { get; set; }
public string SortBy { get; set; }
public int StartRec { get; set; }
public int EndRec { get; set; }
}
public class ValPair {
public int CLI_RID { get; set; }
public string DOC_NAME { get; set; }
}
And you can pass values to the parameters via the following GET API call:
http://www.example.com/api/docs/getDocParams?LogonTicket=111&ValPairs[0][CLI_RID]=111111&ValPairs[0][DOC_NAME]=Letter&ValPairs[1][CLI_RID]=22222&ValPairs[1][DOC_NAME]=document&....
This should work if you know the names of the keys.
First of all, I'm new to MVC.
I want to display the properties of the JSON response in a html view.
For example, i want to get the number of page likes from the JSON response and display just the number of likes on a page.
Any help is much appreciated :)
//
// GET: /Facebook/
public ActionResult Index()
{
var json = new WebClient().DownloadString("https://graph.facebook.com/google");
JsonConvert.DeserializeObject<RootObject>(json);
return view();
}
public class CategoryList
{
public string id { get; set; }
public string name { get; set; }
}
public class Location
{
public string street { get; set; }
public string city { get; set; }
public string state { get; set; }
public string country { get; set; }
public string zip { get; set; }
public double latitude { get; set; }
public double longitude { get; set; }
}
public class Cover
{
public string cover_id { get; set; }
public string source { get; set; }
public int offset_y { get; set; }
public int offset_x { get; set; }
}
public class RootObject
{
public string about { get; set; }
public string awards { get; set; }
public string category { get; set; }
public List<CategoryList> category_list { get; set; }
public int checkins { get; set; }
public string company_overview { get; set; }
public string description { get; set; }
public string founded { get; set; }
public bool is_published { get; set; }
public Location location { get; set; }
public string mission { get; set; }
public string phone { get; set; }
public string products { get; set; }
public int talking_about_count { get; set; }
public string username { get; set; }
public string website { get; set; }
public int were_here_count { get; set; }
public string id { get; set; }
public string name { get; set; }
public string link { get; set; }
public int likes { get; set; }
public Cover cover { get; set; }
}
}
}
Your action should pass the object to the view:
public ActionResult Index()
{
var json = new WebClient().DownloadString("https://graph.facebook.com/google");
var root=JsonConvert.DeserializeObject<RootObject>(json);
return view(root);
}
and then in your view you can show whichever property you want:
#Model RootObject
<html>
<head>
<title>Showing properties</title>
</head>
<body>
#Model.likes likes.
</body>
</html>
This is if you use the Razor syntax.
you're missing
return view(root);
You should pass the object back to view to use it.
you can use JsonResult in mvc 4,
public JsonResult ReturnSomeJson()
{
JsonResult result = new JsonResult();
//Assign some json value to result.
//Allow get is used to get the value in view.
return view(result,AllowGet.True);
}
I was looking for a similar solution and I found it to be a bit different:
[HttpGet]
public JsonResult Index() {
// your code
return Json("some result string or value", JsonRequestBehavior.AllowGet);
}
This outputs "some result string or value" in your browser when you call this action directly.
Assuming this is a normal action inside a controller that
inherits from Controller class.
Most of the tutorials for MVC with Entity Framework are centered around Code-First, where you write classes for generating the model. This gives the advantage of control and Migrations, but I think it lack overview. I would therefore prefer to create the model using the graphical designer, but I cannot see how or if data migrations work in this context. It seems, that when I change the model (with data in the database), all the data is deleted in all tables.
Is there a way around this?
How can I do validation when using Model-First? Partial classes?
you may use the global validation beside mvc validation
example :
public class ValidationCriteria
{
public ValidType Type { get; set; }
public ValidRange Range { get; set; }
public ValidFormat Format { get; set; }
public ValidIsNull IsNull { get; set; }
public ValidCompare Compare { get; set; }
public ValidDB DB { get; set; }
public string Trigger { get; set; }
public Dictionary<string, ValidationCriteria> Before { get; set; }
public string After { get; set; }
public class ValidDB
{
public string functionName { get; set; }
public object[] param { get; set; }
public object functionClass { get; set; }
public string msg { get; set; }
public bool check = false;
}
public class ValidCompare
{
public string first { get; set; }
public string second { get; set; }
public string compareOperator { get; set; }
public string compareValue { get; set; }
public string msg { get; set; }
public bool check = false;
}
public ValidationCriteria()
{
this.Range = new ValidRange();
this.Format = new ValidFormat();
this.IsNull = new ValidIsNull();
this.Type = new ValidType();
this.Compare = new ValidCompare();
this.DB = new ValidDB();
this.Trigger = "blur";
this.Before = new Dictionary<string, ValidationCriteria>();
this.After = "";
}
public class ValidType
{
// checking element is integer.
public bool isInt { get; set; }
// checking element is decimal.
public bool isDecimal { get; set; }
public string msg { get; set; }
public bool check = false;
}
public class ValidRange
{
public long min { get; set; }
public long max { get; set; }
public string msg { get; set; }
public bool check = false;
}
public class ValidFormat
{
public bool isEmail { get; set; }
public string regex { get; set; }
public string msg { get; set; }
public bool check = false;
}
public class ValidIsNull
{
public string nullDefaultVal { get; set; }
public string msg { get; set; }
public bool check = false;
}
}
Meanwhile you may use validation part in your controller
Example :
private bool validateMaintainanceManagement(MaintainanceCRUD.Maintainance model, bool edit = false, bool ServerValidation = true)
{
bool ValidModel = false;
Dictionary<string, ValidationCriteria> validCriteria = new Dictionary<string, ValidationCriteria>();
#region maintainTitle Criteria
ValidationCriteria maintainTitle = new ValidationCriteria();
maintainTitle.IsNull.msg = Resources.Home.ErrmaintainTitle;
maintainTitle.IsNull.check = true;
maintainTitle.IsNull.nullDefaultVal = "-1";
//maintainTitle.Trigger = "change"; // this may trigger if you are using dropdown
validCriteria.Add("maintainTitle", maintainTitle);
#endregion
I am trying to call a method in my controller using ajax and passing an object. I can do this very well when it comes to variables but can't seem to do it using an object. The method is called fine, but the object values are always null. I have also tried using .toJSON method but get this error Uncaught TypeError: Object function (a,b){return new d.fn.init(a,b,g)} has no method 'toJSON' , yes, I have JSON2 included
Here is my attempt so far:
var VoucherDetails = this.GetVoucherDetails();
$.post("/Vouchers/GetVoucherPreviewTemplate", { "Voucher": VoucherDetails},
function (data) {
});
function GetVoucherDetails()
{
var teet = $("#Title").val();
return { Title: teet };
}
C#
[HttpPost]
public ActionResult GetVoucherPreviewTemplate(ENT_Voucher Voucher)
{
return Json("");
}
Here is my ENT_Voucher code:
[Serializable]
public class ENT_Voucher : ENT_VoucherEntityBase
{
public int BusinessID { get; set; }
public int? SiteID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Code { get; set; }
public string Link { get; set; }
public DateTime StartDate { get; set; }
public DateTime ExpiryDate { get; set; }
public string ImageLink { get; set; }
public int Status { get; set; }
public ENT_Business BusinessDetails { get; set; }
public string VoucherTandC { get; set; }
public int Type { get; set; }
public string DaysRemaining { get; set; }
public int RequestCount { get; set; }
public bool IsPetoba { get; set; }
public ENT_Voucher()
{
this.BusinessDetails = new ENT_Business();
}
}
You could send it as a JSON request which allows you to send arbitrarily complex objects:
var VoucherDetails = this.GetVoucherDetails();
$.ajax({
url: '#Url.Action("GetVoucherPreviewTemplate", "Vouchers")',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({ voucher: VoucherDetails }),
success: function(result) {
}
});
If you have JSON2.js included then you want to use JSON.stringify() and pass it the data to serialize in your AJAX call!