0

I have 2 Models. Organization and Site. A org can have many sites but a site can only have 1 org. I have been able to successfully create a page that you can create an org with its primary site and all saves fine into the database.

What id like to do is have a page that shows all the sites for an organization. Id like the url to be something like ~/Organizations/6/Sites. and to see info on a specific site, the url should read ~/organizations/6/sites/2

How would i go about achieving this? Can anyone point me in the right direction. My understanding is that it would be done within the endpoints.MapControllerRoute section under the startup.cs file.

Below are the 2 models and the view action for the org and the viewsites action for the sites which currently both reside in the orgcontroller

public class Organization:BaseEntity
    {


        [Required]
        [Display(Name = "Name")]
        public string Name { get; set; }

        [Display(Name = "Logo")]
        public string Logo { get; set; }

        [Required]
        [Display(Name = "Type")]
        public OrganizationType Type { get; set; }

        [DataType(DataType.DateTime)]
        public DateTime CreatedDate { get; set; }

        [DataType(DataType.DateTime)]
        public DateTime ModifiedDate { get; set; }

        public int Demo { get; set; }

        [Required]
        public bool Active { get; set; }

        public virtual ICollection<Contact> Contacts { get; set; }
        public virtual ICollection<Site> Sites { get; set; }
    }

public class Site : BaseEntity
    {

        [Required]
        [Display(Name = "Name")]
        public string Name { get; set; }

        [Display(Name = "Address")]
        public string FullAddress
        {
            get
            {
                return StreetNumber + " " + StreetAddress + " " + Suburb + " " + State + " " + PostCode + " " + Country;
            }
        }

        [Required]
        [Display(Name = "Street Number")]
        public string StreetNumber { get; set; }

        [Required]
        [Display(Name = "Street Address")]
        public string StreetAddress { get; set; }

        [Required]
        [DataType(DataType.PostalCode)]
        [Display(Name = "Postcode")]
        public string PostCode { get; set; }

        [Required]
        [Display(Name = "Suburb")]
        public string Suburb { get; set; }

        [Required]
        [Display(Name = "State")]
        public string State { get; set; }

        [Required]
        [Display(Name = "Country")]
        public string Country { get; set; }

        [Required]
        [DataType(DataType.PhoneNumber)]
        [Display(Name = "Phone Number")]
        public string PhoneNumber { get; set; }

        [DataType(DataType.DateTime)]
        public DateTime CreatedDate { get; set; }

        [DataType(DataType.DateTime)]
        public DateTime ModifiedDate { get; set; }

        [Required]
        public bool IsPrimary { get; set; }


        public int Demo { get; set; }

        [Required]
        public bool Active { get; set; }

        [Display(Name = "Image")]
        public string Image { get; set; }

        public virtual Organization Organization { get; set; }
    }

 // GET: Organizations/View/5
        public async Task<IActionResult> View(Guid? id)
        {
            if (id == null)
            {
                return NotFound();
            }
            var organization = _context.Organizations.Include("Sites").Include("Contacts").FirstOrDefault(x=> x.ID == id);
            ViewBag.SiteCount = organization.Sites.Count;
            ViewBag.ContactCount = organization.Contacts.Count;
            if (organization == null)
            {
                return NotFound();
            }
            return View(organization);
        }

        // GET: Organizations/View/5
        public async Task<IActionResult> ViewSites(Guid? id)
        {
            if (id == null)
            {
                return NotFound();
            }
            List<Site> sites = _context.Organizations.Include("Sites").Where(x=>x.ID == id).ToList().FirstOrDefault().Sites.ToList();

            return View(sites);
        }

2 Answers 2

1

Here is a working demo like below:

Model:

public class BaseEntity
{
    public Guid Id { get; set; }
}
public class Organization : BaseEntity
{
    [Required]
    [Display(Name = "Name")]
    public string Name { get; set; }

    [Display(Name = "Logo")]
    public string Logo { get; set; }

    [DataType(DataType.DateTime)]
    public DateTime CreatedDate { get; set; }

    [DataType(DataType.DateTime)]
    public DateTime ModifiedDate { get; set; }

    public int Demo { get; set; }

    [Required]
    public bool Active { get; set; }
    public virtual ICollection<Site> Sites { get; set; }
}

public class Site : BaseEntity
{

    [Required]
    [Display(Name = "Name")]
    public string Name { get; set; }

    [Display(Name = "Address")]
    public string FullAddress
    {
        get
        {
            return StreetNumber + " " + StreetAddress + " " + Suburb + " " + State + " " + PostCode + " " + Country;
        }
    }

    [Required]
    [Display(Name = "Street Number")]
    public string StreetNumber { get; set; }

    [Required]
    [Display(Name = "Street Address")]
    public string StreetAddress { get; set; }

    [Required]
    [DataType(DataType.PostalCode)]
    [Display(Name = "Postcode")]
    public string PostCode { get; set; }

    [Required]
    [Display(Name = "Suburb")]
    public string Suburb { get; set; }

    [Required]
    [Display(Name = "State")]
    public string State { get; set; }

    [Required]
    [Display(Name = "Country")]
    public string Country { get; set; }

    [Required]
    [DataType(DataType.PhoneNumber)]
    [Display(Name = "Phone Number")]
    public string PhoneNumber { get; set; }

    [DataType(DataType.DateTime)]
    public DateTime CreatedDate { get; set; }

    [DataType(DataType.DateTime)]
    public DateTime ModifiedDate { get; set; }

    [Required]
    public bool IsPrimary { get; set; }
    public int Demo { get; set; }

    [Required]
    public bool Active { get; set; }

    [Display(Name = "Image")]
    public string Image { get; set; }

    public virtual Organization Organization { get; set; }
}

Controller:

public class OrganizationsController : Controller
{
    private readonly YourDbContext _context;

    public OrganizationsController(YourDbContext context)
    {
        _context = context;
    }

    // GET: Organizations/Details/5
    public async Task<IActionResult> Details(Guid? id,Guid siteId )
    {
        if (id == null)
        {
            return NotFound();
        }

        var organization = await _context.Organization.Include(o=>o.Sites)
            .FirstOrDefaultAsync(m => m.Id == id);
        var site = organization.Sites.Where(x => x.Id == siteId).FirstOrDefault();

        return View(site);
    }
}

Startup.cs:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    //...
    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}/{siteId?}");
    });
}

Result: enter image description here

Request url: https://localhost:portNumber/Organizations/Details/orgnizationid/siteid.

UPDATE:

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
    endpoints.MapControllerRoute(
        name: "custom",
        pattern: "Organizations/{id?}/{sites}/{siteId?}",
        defaults: new { controller = "Organizations", action = "Details" });
});

Or a simple way is to use route attribute:

[Route("[controller]/{id}/sites/{siteId}")]
public async Task<IActionResult> Details(Guid id,Guid? siteId )
Sign up to request clarification or add additional context in comments.

3 Comments

hit ahnsk for this. Id like it to ne Org/*orgid*/Sites
Please check my answer.
public async Task<IActionResult> Details(Guid? id,Guid siteId ) should be (Guid id,Guid? siteId )
0

The way ive done it in the end is

Controller

        // GET: Organizations/5
        // GET: Organizations
        [Route("[controller]/{id?}")]
        public async Task<IActionResult> View(int? id)
        {
            if (id == 0)
            {
                return NotFound();
            }
            if (id == null)
            {
                return View("ViewAll",await _context.Organizations.Include("Sites").Include("Contacts").ToListAsync());
            }
            var organization = _context.Organizations.Include("Sites").Include("Contacts").FirstOrDefault(x=> x.ID == id);
            if (organization == null)
            {
                return NotFound();
            }
            return View("View",organization);
        }

        // GET: Organizations/5/Sites/2
        // GET: Organizations/5/Sites
        // GET: Organizations/5
        [Route("[controller]/{id}/sites/{siteId?}")]
        public async Task<IActionResult> ViewSites(int ordId, int? siteId)
        {
            if (ordId == 0)
            {
                return NotFound();
            }
            if (siteId == 0)
            {
                List<Site> sites = _context.Organizations.Include("Sites").Where(x => x.ID == ordId).ToList().FirstOrDefault().Sites.ToList();
                return View("ViewSites",sites);
            }
            Site site = _context.Organizations.Include("Sites").Where(x => x.ID == ordId).ToList().FirstOrDefault().Sites.ToList().Where(y=>y.ID == siteId).FirstOrDefault();
            return View("ViewSite", site);


        }

Startup.cs

app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "OrgSites",
                    pattern: "Organizations/{id}/{sites}/{siteId?}",
                    defaults: new { controller = "Organizations", action = "ViewSites" });
                endpoints.MapControllerRoute(
                    name: "Orgs",
                    pattern: "Organizations/{id?}",
                    defaults: new { controller = "Organizations", action = "View" });
                endpoints.MapControllerRoute(
                    name: "Orgs",
                    pattern: "Organizations",
                    defaults: new { controller = "Organizations", action = "View" });

                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
                endpoints.MapRazorPages();
            });

2 Comments

if (siteId == 0) should be if (siteId.HasValue) && siteId == 0 your code will throw if sideid is null. Although IMHO, if (siteId.HasValue) && siteid == default(int)) expresses your intent more accurately.
Retrieving a single site should be simplified to Site site = _context.Sites.Where(s=>s.ID == siteId).FirstOrDefault();

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.