I am using Web API 2 with Breeze and Entity Framework 6. I have the following models.
public class ScoreCard: EntityBase
{
public string Title { get; set; }
public virtual List<ScoreCardSection> Sections { get; set; }
public String UserId { get; set; }
}
public class ScoreCardSection:EntityBase
{
public string Title { get; set; }
public int Index { get; set; }
public long ScoreCardId { get; set; }
public virtual List<ScoreCardQuestion> Questions { get; set; }
}
I want to fetch a score card with a list of sections. I execute a EntityQuery with an expand and it executes this URL:
/api/ScoreCards?$filter=Id%20eq%201L&$expand=Sections
I get back the following results:
[{"Title":"Catalyst Service Report","Sections":
[{"Title":"Worship","Index":0,"ScoreCardId":1,"Questions":null,"Id":1},
{"Title":"Message","Index":0,"ScoreCardId":1,"Questions":null,"Id":2},
{"Title":"Leader","Index":0,"ScoreCardId":1,"Questions":null,"Id":3},
{"Title":"Attendance","Index":0,"ScoreCardId":1,"Questions":null,"Id":4},
{"Title":"Security","Index":0,"ScoreCardId":1,"Questions":null,"Id":5}],
"UserId":"b9bd5256-dd18-4c1e-9907-dac9e7e4c01b","Id":1}]
So far, so good. Now we get to the problem. When I inspect the results during the success callback the sections property of the object is a empty array, even though the sections were sent back in the response.
What am I missing here? Thanks in advanced.
Ok, the solution to this problem seemed to be a few hours sleep.
For anyone who has this same issue the first part of the problem was that I didn't have a navigation property for ScoreCard on ScoreCardSection. Once I added that I got a "Self Referencing Loop" error. This was corrected by adding the BreezeControllerAttribute to my controller class.
Hope this is helpful to someone.
Related
I have a slickgrid and am attempting to save its data back to the server.
When I breakpoint on the server, I can see the data in the Request.Form object, but I can't make it work with my object.
My data looks like...
[
{"id":"0","LineNumber":"","Detail":"MOT cost","Code":" ","Qty":"1","Est":" ","CustomerDamage":false,"Cost":"44.00","Value":"44.00","VAT":true,"SelfBillingLine":"False","DefectStatus":" "},
{"id":"62","LineNumber":"","Detail":"CRACKS IN Chassis","Code":"TLMA02","Qty":"1","Est":"","CustomerDamage":false,"Cost":"35.00","Value":"35.00","VAT":true,"SelfBillingLine":"False","DefectStatus":"Large repair"},
{"id":"63","LineNumber":"","Detail":"TEAR IN N/S CURTAIN","Code":"TLMA02","Qty":"1","Est":"","CustomerDamage":true,"Cost":"10.00","Value":"10.00","VAT":true,"SelfBillingLine":"False","DefectStatus":"Customer"}
]
I am posting with a button onclick...
$("#SBSave").click(function() {
debugger;
var details = JSON.stringify(defectrows);
save('SBDetail/SaveSBItem', details);
});
I have tried a number of things to receive the data, none of them work.
My controller...
[HttpPost]
public void SaveSBItem(SelfBillDetailList details, string Approve = "")
{
// Actions here.
}
My model...
Trying a number of things, neither work...
public class SelfBillDetailList
{
public IEnumerable<SelfBillingIncomingDetail> IncomingDetails { get; set; }
}
public class SelfBillingIncomingDetail
{
public int id { get; set; }
public string Code { get; set; }
public string LineNumber { get; set; }
public string Detail { get; set; }
public string Action { get; set; }
public string Qty { get; set; }
public string Est { get; set; }
public bool VAT { get; set; }
public bool CustomerDamage { get; set; }
public string Cost { get; set; }
public string Value { get; set; }
public DateTime Received { get; set; }
public string DefectStatus { get; set; }
public bool SelfBillingLine { get; set; }
}
So, I have tried an individual SelfBillingIncomingDetail and also a the SelfBillDetailList.
Neither work.
I have even sent an individual row, again, neither work.
I want to send it as a group, so it will be an array of SelfBillingIncomingDetail but nothing works.
Thank you for your help.
I have done it again... eventually found an answer after looking for ages.
Darin Dimitrov's answer in
Post an Array of Objects via JSON to ASP.Net MVC3
let me to the answer.
It seems that when sending the data, I need to give the array of data the same name as the property name in SelfBillDetailList, so...
var details = JSON.stringify({IncomingDetails : defectrows});
fixes it.
I my view model(LIST) looks like this:
public class ConversationModel
{
public int ID { get; set; }
public string Body { get; set; }
public DateTime Datetime { get; set; }
public string Username { get; set; }
public string ImgUrl { get; set; }
public string ToUserID{ get; set; }
}
this is my view
#model IEnumerable<NGGmvc.Models.ConversationModel>
how i can get ToUserID on current postion? something like this
#Model[0].ToUserID
Thanks
You should be able to do:
#Model.First().ToUserID
Note, you may want to check whether there are any items in the enumerable first as if there aren't, then First() will return null
(Note, because you had #Model[0] in your question, I assume you are specifically trying to get the first value. I may have the wrong end of the stick, in which case Jakub's answer should sort you out!)
You should be able to use the following:
#Model.First().ToUserID
However, if your model will only ever reference the first element of the enumeration in the view, I would recommend that you only pass that element to the view.
For example:
#model ConversationModel
#Model.ToUserID
And in the controller only pass the first element that is required:
List<ConversationModel> conversationList = //your conversation model initialisation code
return View(conversationList.First());
#foreach(var model in Model)
{
#model.ToUserID
}
I'm trying to expand beyond the "one-to-one" mapping of models to controllers to views that most mvc(3) tutorials offer.
I have models for a person (operator) and the person's picture. In the database they would correspond to Operator and OperatorPicture tables.
public class Operator
{
public Operator()
{
this.OperatorPictures = new HashSet<OperatorPicture>();
}
[DisplayName("Operator ID")]
public int OperatorID { get; set; }
[Required]
[DisplayName("First name")]
[StringLength(20, ErrorMessage = "The first name must be 20 characters or less.")]
public string OperatorFirstName { get; set; }
[Required]
[DisplayName("Last name")]
[StringLength(20, ErrorMessage = "The last name must be 20 characters or less.")]
public string OperatorLastName { get; set; }
public virtual ICollection<OperatorPicture> OperatorPictures { get; set; } // Nav
}
public class OperatorPicture
{
[DisplayName("Operator Picture ID")]
public int OperatorPictureID { get; set; }
[DisplayName("Operator ID")]
public int OperatorID { get; set; }
[DisplayName("Picture")]
public byte[] Picture { get; set; } // 100x100
[DisplayName("Thumbnail")]
public byte[] Thumbnail { get; set; } // 25x25
public virtual Operator theoperator { get; set; } // FK
}
In most views I would present them together. A list of operators would include a thumbnail picture if it exists. Another screen might show the person's detailed information along witht the full-sized picture.
Is this where viewmodels come into play? What is an appropriate way to use them?
Thanks,
Loyd
Definitely a time for using them. ViewModels are just a way of packaging up all the different bits that go into a view or partialview.
Rather than have just the repository pattern, I have repositories and services. The service has a Get property called ViewModel, that can be called from the controller. EG:
// initialise the service, then...
return View(service.ViewModel)
You can see a more detailed description of my approach in the accepted answer for the following SO question:
MVC Patterns
Note that I am using dependency injection in that code.
It may not be a totally orthodox or canonical approach, but it results in very clean controller code and a easy to use pattern.
UPDATE #3: Entire question
I have a class HB:
public class HB
{
public int Id { get; set; }
[StringLength(3000)]
public string Text { get; set; }
public Title Title { get; set; }
}
And Title:
public class Title
{
public int Id { get; set; }
public string Name { get; set; }
public int MaxChar { get; set; }
}
Before you can write a HB (which is kind of an article), you have to choose your title, so your StringLength for HB.Text can be determined. Meaning, this article can only have a certain amount of chars, deppending on what 'Title' the writer has. Example: Title1 can only write a 'HB' with 1000 chars, and Title2 can write a 'HB' with 3000 chars. So. Thats means the the StringLength has to come from Title.MaxChar. Whats the smartest way to do that?
The Title entity is prefixed data that will be stored in the db.
To be crystal clear, what I want to achieve is something in the line with: [StringLength(Title.MaxChar)]
Ive done structure/design for this mechanism in Webforms a million times, my brain just cant addapt to mvc, so some help would be appreciated. Code would be even more appreciated.
Pretty sure that is not possible as written. This strikes me as trying to force business logic into the model that belongs in the controller.
In this situation, I would make the attribute on the Text property [StringLength(3000)]. In the controller, during validation, I would write something along these lines:
public ActionResult (HB model)
{
if (model.Text.Length > model.Title.MaxChar){
ModelState.AddModelError("Text", string.Format("Text for this Title cannot exceed {0} characters.", model.Title.MaxChar));
}
if (ModelState.IsValid)
{
//do stuff
return RedirectToAction("Index"); //or something
}
else
{
return View(model);
}
}
I believe this will accomplish what you are trying to do. Now, for the Title object, I'd flatten that out a bit in your model:
public class HB
{
#region Base Properties
public int Id { get; set; }
[StringLength(3000)]
public string Text { get; set; }
#endregion
#region Title Properties
public int TitleId { get; set; }
public string TitleName { get; set; }
public int TitleMaxChar { get; set; }
#endregion
}
This is assuming you need to display that information in your view. If you just need to reference it for your business logic validation, just have the TitleId property and use that to instantiate the Title object in your controller when you need it. Don't forget to make hidden inputs for each of these properties if they are not editable!
Suppose you have a simple struct, like so:
public struct Point
{
public int X { get; set; }
public int Y { get; set; }
}
And a sample class like so:
public class Map
{
public int ID { get; set; }
public Point? PointA { get; set; }
///...
}
Now, suppose you are passing Map via AJAX as JSON. Question, what value should be passed for the not null scenario?
It may matter that JavaScriptSerializer is being used in a C# 3.5 ASP.NET ASMX web service.
The issue is what I listed in my comment about the question. The automatic properties were the issue. I converted the property and the issue was resolved.