Pro ASP.NET MVC 5 (Expert's Voice in ASP.Net)

Author: Adam Freeman
4.1
This Month Stack Overflow 1

Comments

by anonymous   2017-08-20

The main problem with what you were seeing is that you were not in fact doing anything with the return value of webclient. That is ok though, since based on our discussion everything is in the same project and that would not be how you would want to do this using ASP.NET MVC and Web API.

Since these are all in the same project, we do want to combine common functionality but not within a controller. The DB service should be abstracted away into a seperate project - or class - and then injected into both controllers using some form of IoC Container. There are a couple of options available and I personally usually use Ninject for my .NET projects.

Assuming you have that functionality your MVC Controller and API controller should then both program against that abstraction. Interface based programming is how .NET works best.

With that in mind your new API controller would look something like this:

public IHttpActionResult PostApprovedUsers([Bind(Include="Email, FirstName, LastName")]ApprovedUser approvedUser)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }
        if (_db.UserExists(approvedUser))
        {
            return Content(HttpStatusCode.NotFound, "Email exists Already");
        }

        _db.AddUser(approvedUser);
        return CreatedAtRoute("DefaultApi", new {id = approvedUser.Email}, approvedUser);
    }

Where _db is the service that gets injected into the controller. Please not how common functionality such as checking to see if a user exists and adding a user are wrapped behind the abstraction:

public interface IMyFakeDbService
{
    IQueryable<ApprovedUser> ApprovedUsers { get; }

    int RemoveUser(ApprovedUser user);

    int RemoveUser(string email);

    bool UserExists(ApprovedUser user);

    void AddUser(ApprovedUser user);
}

This then brings us to your MVC Controller. The same principle applies; since all the common functionality is in the db service just inject that into the controller instead of calling the API controller. You will see that you can use ModelState.AddModelError here to pass information back into the view.

public ActionResult Create()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Create([Bind(Include = "Email, FirstName, LastName")]ApprovedUser user)
    {
        if (ModelState.IsValid)
        {
            if (!_db.UserExists(user))
            {
                _db.AddUser(user);
                return RedirectToAction("Index");
            }
            ModelState.AddModelError("","A user with that email already exists");
        }
        return View();
    }

Finally

  1. I made a public git repo with a complete project here
  2. The DB calls should be async. You are wasting server resources if not
  3. If you want to learn MVC real quick I would suggest Pro ASP.NET MVC 5 and Pro ASP.NET Web API2