Post a Javascript array not working with DefaultModelBinder? - asp.net-mvc-3

Code
I can not send an array of javascript objects to the server.
ModelBinder standard does not recognize the format.
On my server I have classes:
public class PessoaViewModel
{
[HiddenInput(DisplayValue = false)]
public int Id { get; set; }
public string Nome { get; set; }
public string Tipo { get; set; }
public string CPF { get; set; }
public ICollection<TelefoneViewModel> Telefones { get; set; }
public ICollection<EnderecoViewModel> Enderecos { get; set; }
public ICollection<EmailViewModel> Emails { get; set; }
public PessoaViewModel Conjuge { get; set; }
}
public class TelefoneViewModel
{
[HiddenInput(DisplayValue = false)]
public int Id { get; set; }
[AdditionalMetadata("class", "span2")]
[AdditionalMetadata("placeholder", "Tipo")]
public string Tipo { get; set; }
[DataType(DataType.PhoneNumber)]
[AdditionalMetadata("class", "span2")]
public string Numero { get; set; }
[HiddenInput(DisplayValue = false)]
public int Ordem { get; set; }
}
I'm not listing the rest of the class because it is not yet used in the code!
My javascript
$.ajax
url: $(form).attr("action")
type: "POST"
error: (err, errType, errMessage) ->
console.error a.statusText
cache: false
data: ko.mapping.toJS(#, ignoreFunctionsMapping)
success: (data, txtStatus) -> console.log "OK!!?? On server maybe not!"
Server result
Full image: http://i.stack.imgur.com/NeIm1.jpg
Question
As you can see, the post is being done and the values ​​are correct.
But asp.net mvc does not fill correctly the Telefones object!
What am I doing wrong?

Your problem is because you are missing a ".", it should have the format:
Telefones[0].Id: 1
Telefones[0].Ordem: bli

Related

Object data send as json is not serializing in object model when calling from postman

I have created an web api using the below code.
[HttpPost]
[Route("api/Agents/SetAgentSettings")]
public HttpResponseMessage SetAgentSetting(string agentIp, string agentMac, Guid orgId,SettingModel settingData)
{
}
From postman I am trying to call this api using the following request.
http://localhost:50194/api/Agents/SetAgentSettings?agentIp=10.0.1.33&agentMac=E442A6273481&orgId=C1F62D47-FBDF-468E-A4E6-418BFD8EB525
And in body I am sending the following body:
{
"agentIp":"10.0.2.10",
"agentMac":"Computer1",
"orgId":"c1f62d47-fbdf-468e-a4e6-418bfd8eb525",
"settingData":"{\"IsAutoSyncActive\":false,\"AutoSyncInterval\":0,\"AutosyncTime\":\"00:00\",\"IsRealtimeSyncActive\":false,\"RealTimeSyncUrl\":null,\"LogTargets\":6,\"LogSeveritys\":15,\"Exports\":0,\"LogInDetail\":true,\"LogInDatabase\":true,\"NotifyEmailId\":null,\"DiagonisticsMode\":false,\"ResyncRule\":null,\"ResyncBatchCount\":\"10\",\"IsResyncScheduled\":false,\"ExecuteFor\":1,\"Batch\":0,\"SaveSyncInfoToDb\":false,\"RealTimePort\":null,\"NotificationRule\":null,\"IsNotificationMailEnabled\":false,\"FileDeleteTime\":null,\"AgentType\":null,\"Frequency\":\"DAILY\",\"PartitionKey\":\"c1f62d47-fbdf-468e-a4e6-418bfd8eb525\",\"RowKey\":\"fbc6b368-9251-4165-a36b-fc1bd3912925\",\"Timestamp\":\"0001-01-01T00:00:00+00:00\",\"ETag\":null}"
}
In controller I am getting every data but setting model is not serializing. How to send the setting model data.
You're passing settingData in JSON string and another side expecting to be bind it with the model, which wouldn't work anyway. You have to pass the model in JSON format. Additionally, as you're passing agentIp, agentMac, orgId in URL, don't need to pass in the body again.
Here I assume your SettingModel as follows,
public class SettingModel
{
public bool IsAutoSyncActive { get; set; }
public int AutoSyncInterval { get; set; }
public string AutosyncTime { get; set; }
public bool IsRealtimeSyncActive { get; set; }
public object RealTimeSyncUrl { get; set; }
public int LogTargets { get; set; }
public int LogSeveritys { get; set; }
public int Exports { get; set; }
public bool LogInDetail { get; set; }
public bool LogInDatabase { get; set; }
public object NotifyEmailId { get; set; }
public bool DiagonisticsMode { get; set; }
public object ResyncRule { get; set; }
public string ResyncBatchCount { get; set; }
public bool IsResyncScheduled { get; set; }
public int ExecuteFor { get; set; }
public int Batch { get; set; }
public bool SaveSyncInfoToDb { get; set; }
public object RealTimePort { get; set; }
public object NotificationRule { get; set; }
public bool IsNotificationMailEnabled { get; set; }
public object FileDeleteTime { get; set; }
public object AgentType { get; set; }
public string Frequency { get; set; }
public string PartitionKey { get; set; }
public string RowKey { get; set; }
public string Timestamp { get; set; }
public object ETag { get; set; }
}
Your request should be:
URL: http://localhost:50194/api/Agents/SetAgentSettings?agentIp=10.0.1.33&agentMac=E442A6273481&orgId=C1F62D47-FBDF-468E-A4E6-418BFD8EB525
Body:
{
"IsAutoSyncActive": false,
"AutoSyncInterval": 0,
"AutosyncTime": "00:00",
"IsRealtimeSyncActive": false,
"RealTimeSyncUrl": null,
"LogTargets": 6,
"LogSeveritys": 15,
"Exports": 0,
"LogInDetail": true,
"LogInDatabase": true,
"NotifyEmailId": null,
"DiagonisticsMode": false,
"ResyncRule": null,
"ResyncBatchCount": "10 ",
"IsResyncScheduled": false,
"ExecuteFor": 1,
"Batch": 0,
"SaveSyncInfoToDb": false,
"RealTimePort": null,
"NotificationRule": null,
"IsNotificationMailEnabled": false,
"FileDeleteTime": null,
"AgentType": null,
"Frequency": "DAILY ",
"PartitionKey": "c1f62d47-fbdf-468e-a4e6-418bfd8eb525",
"RowKey": "fbc6b368-9251-4165-a36b-fc1bd3912925",
"Timestamp": "0001-01-01T00:00:00+00:00",
"ETag": null
}
Method:
[HttpPost]
[Route("api/Agents/SetAgentSettings")]
public void SetAgentSetting(string agentIp, string agentMac, Guid orgId, [FromBody]SettingModel settingData)
{
}

How to avoid to pass null entity object to web api method

I have below web api method as below
public bool UpdateValidations([FromBody] ValidationKeyEntity validationKey)
{
if (ModelState.IsValid)
{
//my code here
}
}
public class ValidationKeyEntity
{
public int ValidationKeyId { get; set; }
[MaxLength(Constants.maxStringLength)]
public string Name { get; set; }
public int DisplayId { get; set; }
[MaxLength(Constants.maxStringLength)]
public string CreatedBy { get; set; }
}
I am doing testing using Postman .I am passing different json than ValidationKeyEntity object as { "Vishal": "vishal" } as parameter .
But still my ModelState.IsValid returns true.
How can I avoid accepting other json object than "ValidationKeyEntity" object?
Use RequiredAttribute to mark the properties as required:
public class ValidationKeyEntity
{
[Required]
public int ValidationKeyId { get; set; }
[Required]
public string Name { get; set; }
[Required]
public int DisplayId { get; set; }
[Required]
public string CreatedBy { get; set; }
}
Set MissingMemberHandling globally to handle waste properties:
var httpConfiguration = new HttpConfiguration();
httpConfiguration
.Formatters
.JsonFormatter
.SerializerSettings
.MissingMemberHandling = MissingMemberHandling.Error;

ServiceStack validators not firing

I am trying to use fluent validation in ServiceStack. I've added the validation plugin and registered my validator.
Plugins.Add(new ValidationFeature());
container.RegisterValidators(typeof(CreateLeaveValidator).Assembly);
I have implemented a validator class for my service model:
public class CreateLeaveValidator : AbstractValidator<CreateLeave>
{
public CreateLeaveValidator()
{
RuleFor(cl => cl.StudentId).NotEmpty();
RuleFor(cl => cl.LeaveDepart).NotEmpty().GreaterThan(DateTime.Now).WithMessage("Leave must begin AFTER current time and date.");
RuleFor(cl => cl.LeaveReturn).NotEmpty().GreaterThan(cl => cl.LeaveDepart).WithMessage("Leave must end AFTER it begins.");
RuleFor(cl => cl.ApprovalStatus).Must( status => ( ("P".Equals(status)) || ("C".Equals(status)) || ("A".Equals(status)) || ("D".Equals(status)) ) );
}
}
Service Model:
[Route("/leaves", "POST")]
public class CreateLeave : IReturn<LeaveResponse>, IUpdateApprovalStatus
{
public int StudentId { get; set; }
public DateTime RequestDate { get; set; }
public DateTime LeaveDepart { get; set; }
public DateTime LeaveReturn { get; set; }
public string Destination { get; set; }
public string HostRelationship { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Postal { get; set; }
public string Hostphone { get; set; }
public string Cellphone { get; set; }
public string Transport { get; set; }
public string Driver { get; set; }
public string Companions { get; set; }
public string Reason { get; set; }
public string ApprovalStatus { get; set; }
public DateTime ApprovalDate { get; set; }
public string ApprovalComment { get; set; }
public string ApprovalReason { get; set; }
public int ApprovalUser { get; set; }
}
But when I create a request with no StudentId or an invalid ApprovalStatus, the validator does not appear to fire and catch the invalid request.
How can I go about troubleshooting the cause of this?
UPDATE: Correction it appears validators are working with my actual service but not in my unit tests. I'm guessing I must not be configuring my apphost correctly in the unit test setup. Here's my test constructor:
public LeaveTests()
{
Licensing.RegisterLicense(#"[license key]");
appHost = new BasicAppHost(typeof(ApiServices).Assembly).Init();
ServiceStack.Text.JsConfig.DateHandler = ServiceStack.Text.DateHandler.ISO8601;
appHost.Plugins.Add(new ValidationFeature());
appHost.Container.RegisterValidators(typeof(CreateLeaveValidator).Assembly);
}
ServiceStack Validation filters are executed in a Global Request Filter which require a full integration test to run, e.g:
public class MyIntegrationTests
{
ServiceStackHost appHost;
public MyIntegrationTests()
{
appHost = new AppHost()
.Init()
.Start("http://localhost:8000/");
}
[OneTimeTearDown] void OneTimeTearDown() => appHost.Dispose();
[Test]
public void Execute_validation_filters()
{
var client = new JsonServiceClient("http://localhost:8000/");
try
{
var response = client.Post(new CreateLeave { ... });
}
catch(WebServiceException ex)
{
//...
}
}
}

Microsoft Cognitive Services Web Search API - DeSerialization Issues

I want to learn Cognitive Services Web Search APIs so I started creating a bot application . I already have a account sub- key and other required information also I read many articles and watch build 2016 videos on this as well.I am having trouble while deserializing the result .
I am not able to find the proxy class that I can use to do that .
The url I am using is https://api.cognitive.microsoft.com/bing/v5.0/search/
and I found a proxy class for previous api version . Can anybody tell me how to get proxy class of the api request / response in VS 2015 for these service.
My Code look like this:
string BingSearchUrl = "https://api.cognitive.microsoft.com/bing/v5.0/search/";
const string bingKey = "Key";
public static async Task<string> Search(string query)
{
var client = HttpClientFactory.Create();
var queryString = BingSearchUrl + "?q=" + query + "&count=10";
// Request headers
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", bingKey);
client.DefaultRequestHeaders.Add("Accept", "application/json");
// Request parameters
string r = await client.GetStringAsync(queryString);
var jsonResult = JsonConvert.DeserializeObject<Bing.ExpandableSearchResult>(r);
return jsonResult.Web.First().Title;
Try below code
public string BingSearchUrl = "https://api.cognitive.microsoft.com/bing/v5.0/search/";
const string bingKey =[KEY];
public async void Search()
{
var client = new HttpClient();
var queryString = HttpUtility.ParseQueryString(string.Empty);
// Request headers
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", bingKey);
// Request parameters
queryString["q"] = "microsoft";
queryString["count"] = "10";
queryString["offset"] = "0";
queryString["mkt"] = "en-us";
queryString["safeSearch"] = "Moderate";
var uri = "https://api.cognitive.microsoft.com/bing/v5.0/news/search?" + queryString;
var response = await client.GetStringAsync(uri);
var jsonResult = JsonConvert.DeserializeObject<BingJson>(response);
string title = jsonResult.value[0].name.ToString();
}
With the jsonResult.value[0] you can loop through the results. First results is at [0] position.
I Created a model class looking at the bing search response json. It looks like,
public class BingJson
{
public string _type { get; set; }
public Instrumentation instrumentation { get; set; }
public string readLink { get; set; }
public int totalEstimatedMatches { get; set; }
public Value[] value { get; set; }
}
public class Instrumentation
{
public string pingUrlBase { get; set; }
public string pageLoadPingUrl { get; set; }
}
public class Value
{
public string name { get; set; }
public string url { get; set; }
public string urlPingSuffix { get; set; }
public Image image { get; set; }
public string description { get; set; }
public About[] about { get; set; }
public Provider[] provider { get; set; }
public DateTime datePublished { get; set; }
public string category { get; set; }
}
public class Image
{
public Thumbnail thumbnail { get; set; }
}
public class Thumbnail
{
public string contentUrl { get; set; }
public int width { get; set; }
public int height { get; set; }
}
public class About
{
public string readLink { get; set; }
public string name { get; set; }
}
public class Provider
{
public string _type { get; set; }
public string name { get; set; }
}
With this model, I am able to get the desired result. The Model which is presented in the other answer is not working in my case.
namespace BingSearchBot
{
public class RootObject
{
public string _type { get; set; }
public WebPages webPages { get; set; }
public RelatedSearches relatedSearches { get; set; }
public RankingResponse rankingResponse { get; set; }
}
public class WebPages
{
public string webSearchUrl { get; set; }
public int totalEstimatedMatches { get; set; }
public List<Value> value { get; set; }
}
public class Value
{
public string id { get; set; }
public string name { get; set; }
public string url { get; set; }
public List<About> about { get; set; }
public string displayUrl { get; set; }
public string snippet { get; set; }
public List<DeepLink> deepLinks { get; set; }
public string dateLastCrawled { get; set; }
public List<SearchTag> searchTags { get; set; }
}
public class About
{
public string name { get; set; }
}
public class DeepLink
{
public string name { get; set; }
public string url { get; set; }
public string snippet { get; set; }
}
public class SearchTag
{
public string name { get; set; }
public string content { get; set; }
}
public class Value2
{
public string text { get; set; }
public string displayText { get; set; }
public string webSearchUrl { get; set; }
}
public class RelatedSearches
{
public string id { get; set; }
public List<Value2> value { get; set; }
}
public class Value3
{
public string id { get; set; }
}
public class Item
{
public string answerType { get; set; }
public int resultIndex { get; set; }
public Value3 value { get; set; }
}
public class Mainline
{
public List<Item> items { get; set; }
}
public class RankingResponse
{
public Mainline mainline { get; set; }
}
}

Using Linq to populate a class

I am getting a weird behavior. I have a class that I created that is used to format data comping from a data entity into a data grid. I am a using a linq query to create a list of the class type from a list of the entity type. Some of the properties of the class are accessible from the linq query but other give me an error. (AMNotStartedPortalDisplay' does not contain a definition for 'ChecklistStatusID'). So my question is why can linq access some properties but not others? I see no reason why this should be happening.
Here is my class:
public class AMWOTPortalDisplay
{
public string DisplayName { get; set; }
public string LOB { get; set; }
public string DisplayProjectPackages { get; set; }
public string ChecklistStatus { get; set; }
public int ChecklistStatusID { get; set; }
public string InstallDate { get; set; }
public string dateToYellow { get; set; }
public string dateToRed { get; set; }
public string ApplicationManager { get; set; }
public string ApplicationManagerLanID { get; set; }
public int ApplicationManagerUserID { get; set; }
public string ImpersonatedManager { get; set; }
public string ImpersonatedManagerLanID { get; set; }
public int ImpersonatedManagerUserID { get; set; }
public string DelegateName { get; set; }
public string DelegateLanID { get; set; }
public int DelegateUserID { get; set; }
public string WOTAssignee { get; set; }
public int ChecklistID { get; set; }
public string DisplayLinkText { get; set; }
public string LinkTextURL { get; set; }
public string rowColor { get; set; }
public string rowTextColor { get; set; }
}
And here is the linq query as I have it so far:
var portaldisplay = checklists
.Select(c => new AMNotStartedPortalDisplay
{
DisplayName = string.Format("{0} ({1})", c.Application.Name, c.Application.ApplicationID),
LOB = c.Application.LOB,
ChecklistStatus = c.ChecklistStatusType.TypeName,
ChecklistStatusID = c.ChecklistStatusTypeID
});
Thanks,
Rhonda
Be careful with your types:
public class AMWOTPortalDisplay
And then:
Select(c => new AMNotStartedPortalDisplay { ... })
It looks like your query should probably be:
Select(c => new AMWOTPortalDisplay { ... })

Resources