Controller always receive null from json only a specify field - asp.net-mvc

Hy folks!
First: I've found these posts before start my question here: questions/11344035 - questions/15939944 - questions/9412449 - questions/9162359 - questions/1551263.
Second: none of then solved my problem... :(
Well, this is my first MVC4 project, and i tryed send per $.ajax my data as follows:
var exames = {
"ExameId": "",
"Valor": "",
"CodLab": "",
"Dias": "",
"LayoutId": ""
};
var apoio = {
"ApoioId": "",
"Razao": "",
"Endereco": "",
"Bairro": "",
"Cidade": "",
"Uf": "",
"Cep": "",
"Telefone": "",
"Fax": "",
"Email": "",
"CodLab": "",
"Obs": "",
"Status": "",
"ArqRotina": "",
"ArqApoio": "",
"Senha": "",
"Exames": []
};
apoio.ApoioId = $("#hdApoioId").val();
apoio.Razao = $("#Razao").val();
apoio.Endereco = $("#Endereco").val();
apoio.Bairro = $("#Bairro").val();
apoio.Cidade = $("#Cidade").val();
apoio.Uf = $("#Uf").val();
apoio.Cep = $("#Cep").val();
apoio.Telefone = $("#Telefone").val();
apoio.Fax = $("#Fax").val();
apoio.Email = $("#Email").val();
apoio.CodLab = $("#CodLab").val();
apoio.Obs = $("#Obs").val();
apoio.Status = $("#Status").val();
apoio.ArqRotina = $("#ArquivoRotina").val();
apoio.ArqApoio = $("#ArquivoApoio").val();
apoio.Senha = $("#SenhaLab").val();
var tbody = document.getElementById(idTabExames).tBodies[0];
var numLinhas = tbody.rows.length;
for (var i = 0; i < numLinhas; i++) {
exames.ExameId = tbody.rows[i].cells[0].firstChild.nodeValue.toString();
exames.CodLab = tbody.rows[i].cells[1].firstChild.nodeValue;
exames.Dias = tbody.rows[i].cells[2].firstChild.nodeValue;
exames.Valor = tbody.rows[i].cells[3].firstChild.nodeValue;
exames.LayoutId = tbody.rows[i].cells[4].firstChild.nodeValue;
apoio.Exames.push(exames);
exames = {
"ExameId": "",
"CodLab": "",
"Dias": "",
"Valor": "",
"LayoutId": "",
"ApoioId": ""
};
}
$.ajax({
url: '/ApoioExames/Create',
data: JSON.stringify(apoio),
type: 'POST',
contentType: "application/json",
dataType: 'json',
processData: true,
success: function (result) {
if (result.Success == "1") {
if (console.window) console.log('sucess: '+result);
window.location.href = "/ApoioExames/Index";
}
else {
alert(xhr.status);
alert('Error: ' + xhr.responseText);
}
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
}
});
Applying JSON.stringfy(apoio), I get a return of valid json (verified with http://jsonlint.com) but the apoio.Exames field (only it) is null on my controller. Always!
[HttpPost]
public JsonResult Create(ApoioModel apoio)
{
try
{
if (ModelState.IsValid)
{
if (apoio.Id > 0)
{
var exames = db.DbApoioExames.Where(p => p.ApoioId == apoio.Id);
foreach (ApoioExmModel exm in exames)
db.DbApoioExames.Remove(exm);
foreach (ApoioExmModel exm in exames)
db.DbApoioExames.Add(exm);
db.Entry(apoio).State = EntityState.Modified;
}
else
{
db.DbApoio.Add(apoio);
}
db.SaveChanges();
//If (Sucess== 1) { Salvar/Atualizar } else { Exception }
return Json(new { Success = 1, ApoioId = apoio.Id, ex = "" }, JsonRequestBehavior.AllowGet);
}
}
catch (Exception ex)
{
return Json(new { Success = 0, ex = ex.Message }, JsonRequestBehavior.AllowGet);
}
return Json(new { Success = 0, ex = new Exception("Impossível Salvar").Message }, JsonRequestBehavior.AllowGet);
}
My model ApoioModel and ApoioExmModel are:
[Table(name: "apoio", Schema = "public")]
public class ApoioModel
{
[Key, Column("id", Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Column("razao")]
[Display(Name = "Razão Social")]
[DataType(DataType.Html)]
[Required(ErrorMessage = "A razão social deve ser informada")]
public string Razao { get; set; }
[Display(Name = "Endereço")]
[Column("endereco")]
public string Endereco { get; set; }
[Display(Name = "Bairro")]
[Column("bairro")]
public string Bairro { get; set; }
[Display(Name = "Cidade")]
[Column("cidade")]
public string Cidade { get; set; }
[Display(Name = "CEP")]
[Column("cep")]
public string Cep { get; set; }
[Display(Name = "UF")]
[Column("uf")]
[StringLength(2)]
public string Uf { get; set; }
[Display(Name = "Status")]
[Range(0, 1), Column("status")]
public int Status { get; set; }
public virtual ICollection<ApoioExmModel> ApoiosExm { get; set; }
}
Table(name: "apoioexm", Schema = "public")]
public class ApoioExmModel
{
[Key, Column("id")]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int? Id { get; set; }
[Column("exame_id")]
public int ExameId { get; set; }
[Column("apoio_id")]
public int ApoioId { get; set; }
[Column("valor")]
public float Valor { get; set; }
[Column("codlab")]
public string CodLab { get; set; }
[Column("dias")]
public float Dias { get; set; }
[Column("layout_id")]
public int LayoutId { get; set; }
[ForeignKey("ApoioId")]
public virtual ApoioModel Apoios { get; set; }
}
I am trying create a CRUD master/detail. I am using Postgre, not SQL Server, but this is not the problem.
When I am debugging in Chrome, I view the data is transfering ok!
Request U R L : h t t p : / / l o c a l h o s t:9795/ApoioExames/Create
Request Headersview source
Accept:application/json, text/javascript, */*; q=0.01
Content-Type:application/json
Origin:h t t p : / / localhost:9795
Referer: h t t p : / / localhost:9795/ApoioExames/Create
User-Agent:Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31
X-Requested-With:XMLHttpRequest
Request Payload
{Razao:kkkkkkk, Endereco:kkkkkkkkk, Bairro:kkkkkk, Cidade:kkkk, Uf:kk, Cep:12341234,…}
Bairro: "kkkkkk"
Cep: "12341234"
Cidade: "kkkk"
Endereco: "kkkkkkkkk"
Exames: [{ExameId:1252, Valor:1, CodLab:1, Dias:1, LayoutId:1826},…]
0: {ExameId:1252, Valor:1, CodLab:1, Dias:1, LayoutId:1826}
1: {ExameId:1252, CodLab:1, Dias:1, Valor:1, LayoutId:1826, ApoioId:}
Razao: "kkkkkkk"
Uf: "kk"
Someone help me?
Sorry my bad english and the large post!
Thanks!

I have two things in mind.
ApoiosExm should be named Exames or vice-versa
I'm not sure if it can map to a ICollection<ApoioExmModel>. Either way, if you ask me, I would recommend not mapping directly to your entity classes.

Related

DocumentDB LINQ Query - Select method not supported

The Application:
.Net Standard Class Library (Containing a series of Repositories)
Latest version https://www.nuget.org/packages/Microsoft.Azure.DocumentDB.Core
Azure Cosmos DB Emulator
Sample Document Structure:
{
"ProfileName": "User Profile 123",
"Country": "UK",
"Tags": [{
"Id": "686e4c9c-f1ab-40ce-8472-cc5d63597263",
"Name": "Tag 1"
},
{
"Id": "caa2c2a0-cc5b-42e3-9943-dcda776bdc20",
"Name": "Tag 2"
}],
"Topics": [{
"Id": "baa2c2a0-cc5b-42e3-9943-dcda776bdc20",
"Name": "Topic A"
},
{
"Id": "aaa2c2a0-cc5b-42e3-9943-dcda776bdc30",
"Name": "Topic B"
},
{
"Id": "eaa2c2a0-cc5b-42e3-9943-dcda776bdc40",
"Name": "Topic C"
}]
}
The Problem:
The issue I have is that any LINQ query I execute that contains a .Select, returns an error stating that the Select method is not supported.
What I Need?
I want to be able to use a LINQ Expression to return all documents WHERE:
Country = UK
Tags contains a specific GUID
Topics contain a specific GUID
What I Need? I want to be able to use a LINQ Expression to return all documents
In your case, the Tags and Topic are object array, if you use the following linq code it will get null.
var q = from d in client.CreateDocumentQuery<Profile>(
UriFactory.CreateDocumentCollectionUri("database", "coll"))
where d.Country == "UK" && d.Tags.Contains(new Tag
{
Id = "686e4c9c-f1ab-40ce-8472-cc5d63597264"
}) && d.Topics.Contains(new Topic
{
Id = "baa2c2a0-cc5b-42e3-9943-dcda776bdc22"
})
select d;
I also try to override IEqualityComparer for Tag and Topic
public class CompareTag: IEqualityComparer<Tag>
{
public bool Equals(Tag x, Tag y)
{
return x != null && x.Id.Equals(y?.Id);
}
public int GetHashCode(Tag obj)
{
throw new NotImplementedException();
}
}
And try it again then get Contains is not supported by Azure documentDb SDK
var q = from d in client.CreateDocumentQuery<Profile>(
UriFactory.CreateDocumentCollectionUri("database", "coll"))
where d.Country == "UK" && d.Tags.Contains(new Tag
{
Id = "686e4c9c-f1ab-40ce-8472-cc5d63597264"
},new CompareTag()) && d.Topics.Contains(new Topic
{
Id = "baa2c2a0-cc5b-42e3-9943-dcda776bdc22"
}, new CompareTopic())
select d;
My workaround is that we could use the SQL query directly. It works correctly on my side. We also could test it on the Azure portal.
SELECT * FROM root WHERE (ARRAY_CONTAINS(root.Tags, {"Id": "686e4c9c-f1ab-40ce-8472-cc5d63597263"}, true) And ARRAY_CONTAINS(root.Topics, {"Id": "baa2c2a0-cc5b-42e3-9943-dcda776bdc20"}, true) And root.Country = 'UK' )
Query with SDK
FeedOptions queryOptions = new FeedOptions { MaxItemCount = -1 };
var endpointUrl = "https://cosmosaccountName.documents.azure.com:443/";
var primaryKey = "VNMIT4ydeC.....";
var client = new DocumentClient(new Uri(endpointUrl), primaryKey);
var sql = "SELECT * FROM root WHERE (ARRAY_CONTAINS(root.Tags, {\"Id\":\"686e4c9c-f1ab-40ce-8472-cc5d63597263\"},true) AND ARRAY_CONTAINS(root.Topics, {\"Id\":\"baa2c2a0-cc5b-42e3-9943-dcda776bdc20\"},true) AND root.Country = \"UK\")";
var profileQuery = client.CreateDocumentQuery<Profile>(
UriFactory.CreateDocumentCollectionUri("dbname", "collectionName"),sql, queryOptions).AsDocumentQuery();
var profileList = new List<Profile>();
while (profileQuery.HasMoreResults)
{
profileList.AddRange(profileQuery.ExecuteNextAsync<Profile>().Result);
}
Profile.cs file
public class Profile
{
[JsonProperty(PropertyName = "id")]
public string Id { get; set; }
public string Country { get; set; }
public string ProfileName { get; set; }
public Tag[] Tags{ get; set; }
public Topic[] Topics { get; set; }
}
Topic.cs
public class Topic
{
public string Id { get; set; }
public string Name { get; set; }
}
Tag.cs
public class Tag
{
public string Id { get; set; }
public string Name { get; set; }
}

Error Trying to pass a IEnumerable list with Linq and Mvc Web API

I'm trying to return a result from a list with a Linq method but i get an error saying that I "implictly can't convert my class to generic list. I'm using Get... method.
Would very much appreciate if someone could help me out with this.
This is my Tamagotchi class:
public class Tamagotchi
{
public string Name { get; set; }
public DateTime Born { get; set; }
public int Health { get; set; }
}
This is the API:
public class SomeController : ApiController
{
List<Tamagotchi> Gotchis = new List<Tamagotchi>
{
new Tamagotchi { Born = DateTime.Now.AddYears(-5), Health = 30, Name = "XTP" },
new Tamagotchi { Born = DateTime.Now.AddYears(-4), Health = 49, Name = "ZQX" },
new Tamagotchi { Born = DateTime.Now.AddYears(-3), Health = 15, Name = "VBR" },
new Tamagotchi { Born = DateTime.Now.AddYears(-2), Health = 87, Name = "BNQP" },
new Tamagotchi { Born = DateTime.Now.AddYears(-1), Health = 62, Name = "VLW" },
};
public IEnumerable<Tamagotchi> Get2()
{
var _result = Gotchis.SingleOrDefault(tama => tama.Name == "VLW");
return _result;
}
}
Thank you!
/Chris
SingleOrDefault will return a single Tamagutchi, so the result is not an IEnumerable at all. Perhaps you mean
public Tamagotchi Get2()
{
var _result = Gotchis.SingleOrDefault(tama => tama.Name == "VLW");
return _result;
}
or
public IEnumerable<Tamagotchi> Get2()
{
var _result = Gotchis.Where(tama => tama.Name == "VLW");
return _result;
}

Customized StringLength Validation doesn't work

I added Customized StringLength class in my project
using System;
using System.ComponentModel.DataAnnotations;
namespace Argussoft.BI.DAL.Validation
{
public class PasswordLengthAttribute : StringLengthAttribute
{
public PasswordLengthAttribute(int maximumLength)
: base(maximumLength)
{
}
public override bool IsValid(object value)
{
string val = Convert.ToString(value);
if (val.Length < MinimumLength)
ErrorMessage = "Минимальная длина пароля 5 символов";
if (val.Length > MaximumLength)
ErrorMessage = "Максимальная длина пароля 20 символов";
return base.IsValid(value);
}
}
}
It's my class CreateUserDto
public class CreateUserDto
{
[Required(ErrorMessage = "Введите пароль")]
[PasswordLength(User.PasswordMaxLength, MinimumLength = User.PasswordMinLength)]
[RegularExpression(User.PasswordRegularExpression, ErrorMessage = "Пароль может содержать только латинские символы, дефисы, подчеркивания, точки")]
public virtual String Password { get; set; }
}
And it's my controller
[HttpPost]
public ActionResult CreateUser(CreateUserDto dto)
{
if (!Request.IsAjaxRequest()) return View("_AddUserDialog", dto);
if (!ModelState.IsValid) {FillViewBags(); return PartialView("_AddUserDialog", dto);}
string hash;
string salt;
CryptoUtils.SetHashAndSalt(dto.Password, out hash, out salt);
UserService.CreateUser(
new User ()
{
Name = dto.Name,
Email = dto.Email,
FullName = dto.FullName,
Role = UserService.SetRole(dto.Role),
Phone = dto.Phone,
Status = UserService.SetUserStatus(dto.Status),
PasswordHash = hash,
PasswordSalt = salt
});
return Json(new { Message = string.Format("Пользователь {0} успешно создан", dto.Name) });
}
but if I try to enter the password is less than 5 characters or more than 20, ModelState.IsValid == false, but
I don't get any error message when the password is less than 5 characters or more than 20. What's wrong?

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;
}

A circular reference was detected while serializing an object of type?

DB MetersTree TABLE
id text parentId state
0 root 0 open
1 level 1 1 open
2 level 1 1 open
...
CONTROLLER
public ActionResult GetDemoTree()
{
OsosPlus2DbEntities entity = new OsosPlus2DbEntities();
MetersTree meterTree = entity.MetersTree.FirstOrDefault();
return Json(meterTree, JsonRequestBehavior.AllowGet);
}
DATA FORMAT THAT SHOULD BE (for example)
[{
"id": 1,
"text": "Node 1",
"state": "closed",
"children": [{
"id": 11,
"text": "Node 11"
},{
"id": 12,
"text": "Node 12"
}]
},{
"id": 2,
"text": "Node 2",
"state": "closed"
}]
How can I create tree Json Data? If I write MetersTree with its relationships I get the error that is defined in the title.
You need to break the circular reference that is being picked up because of the navigational property in your EF class.
You can map the results into an anonymous type like this, although this is untested:
public ActionResult GetDemoTree()
{
OsosPlus2DbEntities entity = new OsosPlus2DbEntities();
MetersTree meterTree = entity.MetersTree.FirstOrDefault();
var result = from x in meterTree
select new
{
x.id,
x.text,
x.state,
children = x.children.Select({
c => new {
c.id,
c.text
})
};
return Json(result, JsonRequestBehavior.AllowGet);
}
I solved it like this:
VIEW MODEL
public class MetersTreeViewModel
{
public int id { get; set; }
public string text { get; set; }
public string state { get; set; }
public bool #checked { get; set; }
public string attributes { get; set; }
public List<MetersTreeViewModel> children { get; set; }
}
CONTROLLER
public ActionResult GetMetersTree()
{
MetersTree meterTreeFromDb = entity.MetersTree.SingleOrDefault(x => x.sno == 5); //in my db this is the root.
List<MetersTreeViewModel> metersTreeToView = buildTree(meterTreeFromDb.Children).ToList();
return Json(metersTreeToView, JsonRequestBehavior.AllowGet);
}
BuildTree Method
private List<MetersTreeViewModel> BuildTree(IEnumerable<MetersTree> treeFromDb)
{
List<MetersTreeViewModel> metersTreeNodes = new List<MetersTreeViewModel>();
foreach (var node in treeFromDb)
{
if (node.Children.Any())
{
metersTreeNodes.Add(new MetersTreeViewModel
{
id = node.sno,
text = node.Text,
state = node.Text,
children = BuildTree(node.Children)
});
}
else {
metersTreeNodes.Add(new MetersTreeViewModel
{
id = node.sno,
text = node.Text,
state = node.Text
});
}
}
return metersTreeNodes;
}
Thanks to all who are interested in ...

Resources