cfraser
cfraser

Reputation: 961

What would be the right way for adding new elements to DB?

I'm sorry for the vague title, I don't know how to explain this concisely.

I'm building a demo app in ASP.NET with Entity Framework, that displays Spotify artists' and their albums' info, but first, the user has to add an artist to the DB before being able to check that artist info.

So, we have the model, view and controller for the Artist and Album classes.

And when a user adds an artist from the site, through a form, it goes to the the ArtistController class to the Create method.

// POST: Artists/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "ArtistID,ArtistName")] Artist artist)
{
    if (ModelState.IsValid)
    {
        db.Artists.Add(artist);
        db.SaveChanges();
        return Json(new { success = true }, JsonRequestBehavior.AllowGet);
    }
    return Json(new { success = false }, JsonRequestBehavior.AllowGet);
}

(I edited it to return a JSON, because the user is supposed to search for an artist, and then add the one they want from the results list with an AJAX call).

So what to do after adding an artist? I want to add their albums to the DB now, but how should I do it? I need to make an AJAX call again to Spotify to get this artist albums and add them.

So, is it a good practice to add something like AlbumsController.addAlbumsForArtist(ArtistID) , for example, just before the return Json(new { success = true }, JsonRequestBehavior.AllowGet);? And then in addAlbumsForArtist in AlbumsController make an AJAX call to Spotify for this artist albums, and add them. I think this is the best option, but I'm not really sure about the how-to's in ASP.NET about how do it (What's the best way to call a controller from another controller? It is OK to create the addAlbumsForArtist in AlbumsController? How should I go for calling that method? Make it static?)

Also, kinda unrelated, but what's the difference between SaveChanges() and SubmitChanges() for the DB?

Upvotes: 0

Views: 56

Answers (1)

gerrod
gerrod

Reputation: 6637

This is a pretty big question and hard to answer specifically, but I'll try to give you a bit of guidance.

What's the best way to call a controller from another controller?

Short answer: don't do it.

One architectural approach that may help here is to use services to do the heavy lifting for you. e.g. lets say you created an IAlbumService as follows:

public interface IAlbumService
{
    Task<IAlbum[]> GetAlbumsForArtist(int artistId);   
}

Then you'd have to provide an implementation for it; something like:

public class AlbumService : IAlbumService
{
    public Task<IAlbum[]> GetAlbumsForArtist(int artistId)
    {
        // todo: hit spotify API and get albums.
        var albums = new[]
        {
            new Album { Title = "Fabo sounds from the 70s" },
            new Album { Title = "Just can't get enough nutella" }
        };

        return Task.FromResult(albums);
    }
}

Now, you can use dependency injection to provide your controller with an instance of the Album Service; the constructor for your ArtistController might become:

private IAlbumService _albumService;

public ArtistController(IAlbumService albumService)
{
    _albumService = albumService;
}

Now your Create method would be:

public async Task<ActionResult> Create([Bind(Include = "ArtistID,ArtistName")] Artist artist)
{
    if (!ModelState.IsValid) return Json(new { success = false });

    db.Artists.Add(artist);

    var albums = await _albumService.GetAlbumsForArtist(artist.ArtistID);
    foreach (var album in albums)
    {
        db.Albums.Add(albums)
    }

    db.SaveChanges();

    return Json(new { success = true }, JsonRequestBehavior.AllowGet);
}

This still isn't fantastic - you definitely shouldn't be doing so much work in your controller - but it's a step in the right direction. Hope that helps!

Upvotes: 2

Related Questions