I'm using ASP.NET Web API 2 for the backend and AngularJS for the frontend. I want to display a treeview in AngularJS.
So I need a nested Model in my ASP Web API. The model currently looks like this:
public class Register
{
public int ID { get; set; }
public string Name { get; set; }
public List<Register> Children { get; set; }
}
and the controller like this:
// GET: api/Registers
public IQueryable<Register> GetRegister()
{
return db.Register;
}
In my Database I added following examples:
The JSON Output shows:
[{"ID":4,"Name":"RootFolder","Children":[{"ID":5,"Name":"Sub1","Children":null}]},{"ID":5,"Name":"Sub1","Children":null}]
The first entry looks fine, but I don't want to output the children itself. It it possible to only output the RootFolder with its Children and not the children itself? Like this:
{"ID":4,"Name":"RootFolder","Children":[{"ID":5,"Name":"Sub1","Children":null}]}
The second problem is, when I want enter a specific Folder ID (For example ID 4(RootFolder)). I only get this as a response:
Why there are no child elements? The controller is this one:
// GET: api/Registers/5
[ResponseType(typeof(Register))]
public IHttpActionResult GetRegister(int id)
{
Register register = db.Register.Find(id);
if (register == null)
{
return NotFound();
}
return Ok(register);
}
Summary:
How can I filter the Output to only show the RootFolders with each children but not showing the children objects itself?
Why there are no children when I specify a specific ID?
I guess you are using entity framework for database operations.
For the first point, you need to filter root folder row e.g. for root Register_ID is null
db.Register.Where(x => x.Register_ID == null && x.ID==ID).ToList()
For second point to load root folder's children you can include it's navigation property, for example refer below code.
db.Register.Include(x => x.Children).Where(x => x.Register_ID == null).ToList();
Related
I have the following json Object which i am sending to Web Api controller Using ajax.
var dataObject = {
LanguageId: 1,
SubTenantId: 1,
Object:{"TestApplication":{"Aplication":null}}
}
Controller function RequestObject generic class.
public IHttpActionResult ComplexObject(RequestObject<TestApplicationMain> pubRequestObject)
I am using following Class hierarchy.
public class TestApplicationMain
{
public TestApplicationMain()
{
TestApplication = new TestApplication();
}
public TestApplication TestApplication{get; set;}
}
public class TestApplication
{
public TestApplication()
{
Aplication = new List<ApplicationSearchParam>();
}
public List<ApplicationSearchParam> Aplication { get; set; }
}
public class ApplicationSearchParam
{
public ApplicationSearch ApplicationSearch { get; set; }
public string OrderBy { get; set; }
}
When i send {"TestApplication":{"Aplication":null}} json to the controller. I receive One item Aplication .
Api controller works as expected when i send {"TestApplication":{"Aplication":undefined}} OR {"TestApplication":{"Aplication":[]}}
My Question is Why Asp.net WebApi Controller add one item in nested child list when its set to null ?.
First Problem Spotted:
var dataObject = {
LanguageId: 1,
SubTenantId: 1,
Object:{"TestApplication":{"Aplication":null}}
}
Your JSON is at a level higher than TestApplicationMain
You defined LanguageId and SubTenantId but your receiving class TestApplicationMain does not handle either of the values.
You have not defined Object in TestApplicationMain
The reason your first test scenario {"TestApplication":{"Aplication":null}} works is because TestApplication is a property of TestApplicationmain
When you are automapping JSon Key-Value pairs, the name of the Key needs to match the name of the Property you wish its value to be assigned.
You test JSON should be:
var dataObject = {"TestApplication":{"Aplication":""}}
as this structure would map to:
TestApplicationMain -> TestApplication -> Aplication = ""
My Suggestions:
https://stackoverflow.com/a/31022729/659246
https://www.strathweb.com/2013/06/supporting-only-json-in-asp-net-web-api-the-right-way/
I made a register page with dynamic form in Orchard CMS, and received new requirements of checking record count.
I have no idea about how to do this, I looked into the SubmissionAdminController.cs in Orchard.DynamicForms.Controllers folder, but still could not find a way.
I'm thinking to get the record count from my cshtml view page and check it in different parts, is it possible?
To get the record count of the stored submissions, inject or resolve an IRepository<Submission>, and use the Count() method to count all items. Note that the Count() method accepts an expression, which allows you to filter by form name for example. For reference, this is what the Submission class looks like:
namespace Orchard.DynamicForms.Models {
public class Submission {
public virtual int Id { get; set; }
public virtual string FormName { get; set; }
[StringLengthMax]
public virtual string FormData { get; set; }
public virtual DateTime CreatedUtc { get; set; }
}
}
When you have an IRepository<Submission>, this is how you would count all submissions in a form called "MyForm":
var count = submissionRepository.Count(x => x.FormName == "MyForm");
If you don't have a controller or custom part or anything to inject this IRepository into, then you could resolve the repository directly form your view like this:
#{
var submissionRepository = WorkContext.Resolve<IRepository<Submission>>();
var submissionCount = submissionRepository.Count(x => x.FormName == "MyForm");
}
Make sure to import the proper namespaces:
Orchard.DynamicForms.Models for Submission
Orchard.Data for IRepository<T>
However, if you need to display this number in multiple places, it's best to create a shape so that you can reuse it. Even better would be to not resolve the repository from the shape template directly, but via an IShapeTableProvider. The primary reason for that becomes clear when you start overriding your shape template or start providing shape alternates, both in which cases you'll have duplicate logic in all of your shape templates, which isn't very DRY of course. And there's the more philosophical issue of separation of concerns: you don't want data access code in your views. Rather, use that code from a controller, driver or shape table provider.
I'm in the process of designing a RESTful Web API and have bumped into the following problem: I need a controller to retrieve collections (called Sections) of a hierarchical structure as well as to retrieve a single part (a single Section). If I need a collection I have to refer to the ID of the root Section which gives me a subtree of the whole structure. So I went ahead and defined a SectionsController like this:
public class SectionsController : ApiController
{
// GET api/sections/5
// Gets a subtree.
public IEnumerable<Section> Get(int rootId)
{
...
}
// GET api/sections/5
// Gets a single section.
public Section Get(int sectionId)
{
...
}
Which obviously doesn't work as the signatures are identical. What is the recommended way to go about this?
If you want to follow standard REST patterns you should introduce a slightly different API:
public class SectionsController : ApiController
{
// GET api/section
public IEnumerable<Section> GetAll()
{
...
}
// GET api/section/5
public Section Get(int sectionId)
{
...
}
Normally you should use singular resources and provide identifier only for a specific one. You can't have same URLs, even with different controllers.
Reading this post on SO regarding image transfer and following the link provided I realized there is a very simple solution to this problem that respects REST and at the same time doesn't require additional controllers.
Just return a collection of the subtree IDs within the object requested for a particular ID, i.e.
public class Section
{
public int Id { get; set; }
public string Name { get; set; }
public int[] DescendantIds { get; set; }
}
So with a single call to
api/section/5
I get all the details for the section with ID 5 as well as the IDs of the sections below. Yes, there's some overhead involved, so you have to decide for yourself if this solution is for you.
question about collection helper classes for view models with in a Web API <> View Models <> Entity Framework <> Database structure.
I'm trying to get a design started on a project which will use an "API" front end to get data, then HTML/Javascript pages to get and render.
In trying to create an MVVM approach to this I am not sure if what I want to implment is a good approch or not.
And that is a get Collection methods for the ViewModels. The user on the HTML side, will only be able to edit one Object at a time, so the collection is only to provide arrays/listing of the objects, making the Web API classes "less cluttered".
Using the Visual Studio MVC/Web API porject / c# (Visual Studio 2013 so MVC 5 components)
so using example of a Chair object
NOTE: in actual code would not do "new MyEntity().Chairs." all the time, it would be set as a variable with in the class. Simply written example long hand to make clear.
Web API part:
we will pluralize api objects front point
Web API controller = ChairsController
With 2 gets
namespace FurnitureAPI.Controllers
{
[Authorize]
public class ChairsController : ApiController
{
// GET api/chairs
public IHttpActionResult Get()
{
var chairs = ViewModels.Chairs.Get();
return Ok(chairs);
}
// GET api/chairs/5
//public string Get(int id)
public IHttpActionResult Get(int id)
{
var chair = ViewModels.Chairs.Get(id);
return Ok(chair);
}
public ... GET() {...} //all chairs
public ... GET(int id) {} //single chair where id
In the database side, we have Chair table. This will be singular for database.
Database already exists, so using Entity Framework and database first modelling we get in Entities
var furniture_db = new Models.FurnintureEntities();
and
Models.Chair
So in the middle want a View Model Chair.
namespace FurnitureAPI.ViewModels {
public class Chair {
public int ChairID { get; set; }
public string Name { get; set; }
public Chair() { }
public Chair(int chairid, string name) {
ChairID = chairid;
Name = name;
}
public Chair(Models.Chair db_chair) {
ChairID = db_chair.ChairID;
Name = db_chair.Name;
}
}
In my thinking, the Web API ChairsController I do not want to have any entity framework code.
but I want api to call something to get a List/Collection of Chair view models
So Im thinking, add Chairs as a class in the ViewModel namespace, which will be static.
so web api becomes
public IHttpActionResult Get()
{
var chairs = ViewModels.Chairs.Get();
return Ok(chairs);
}
and the View Model Collection Chairs then looks like
namespace FurnitureAPI.ViewModels {
public static class Chairs {
public static List<Chair> Get() {
List<Chair> chairs = (from s in new Models.FurnintureEntities().Chairs
select new ViewModel.Chair {
ChairID = s.ChairID,
Name = s.Name
}).ToList();
return chairs;
}
public static Chairs Get(int id) {
var chair = new FurnitureEntities().Chairs.SingleOrDefault(c => c.ChairID == id);
return chair != null ? new ViewModel.Chair(chair) : null;
}
}
So the question, is this Chairs collection wrapper okay/ideal/bad/run for the hills/other, or is there a different approach someone could point to?
I do not understand why struggling to find reference to on the internet, sure hope its not grumpy old age kicking in.
I find lots of WPF MVVM Entity Framework database first stuff, but I just want to make 'simple' Web API to expose the database to make HTML views with.
Maybe I do not need to bother with the View Model and simply serialize the Entity in the Web API methods?
Thanks.
Unfortunately I've been struggling with this too and it seems this subject doesn't get the love it should have.
Anyway, among the tools there are, you can count:
Breeze# (MIT)
TrackableEntitities (MIT)
I'm having an impossible time figuring out why my returned child entities are null for a particular query:
The item has a child property with a 0 or 1 multiplicity called MetaDataItem.
var res = ObjectContext.Contents.Include("MetaDataItem");
This works. I can confirm that res contains 1 instance of MetaDataItem.
On the client:
var loadOperation = _cContext.Load(_cContext.GetItemQuery(itemId.Value)....
Content item = _cContext.Contents.First(c => c.ContentId == itemId.Value);
Here item.MetaDataItem is null instead of containing the one instance.
Here is the metadata class (note that I DO have an include attribute):
[MetadataTypeAttribute(typeof(Content.ContentMetadata))]
public partial class Content
{
internal sealed class ContentMetadata
{
[Include]
public MetaDataItem MetaDataItem { get; set; }
}
}
So, why isn't my object populating? What else should I be looking at? Unfortunately, this appears to be where the magic of RIA services occurs, so I can't even really get a handle on attempting to debug the issue. Any help would be most appreciated.