For the first time ever, I'm integrating an MVC website to an ASP.NET Web API 2 web service (both of which are coded by myself).
I'd appreciate it if you can just look this over for me and let me know if I'm on the right track here as far as the integration goes.
I'm working based on this tutorial but I had a little trouble along the way.
What I need to know is:
- Am I missing anything in either the service controller or the client controller that I should have - any oversight?
- Is my MVC controller totally thread safe (i.e. is anything going to be blocked with the asyncronysity?
- Is there a better or more efficient way to do anything that I'm doing here?
This is just a simple request/respond scenario where the web service acts as the middle-man between the application and the database so it's really nothing special.
Here's the code for the web service controller:
public class UserController : ApiController
{
OrtundServiceEntities db = new OrtundServiceEntities();
public HttpResponseMessage Get()
{
List<User> users = db.Users.ToList();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, users);
return response;
}
public HttpResponseMessage Get(int Id)
{
User u = db.Users.Single(x => x.Id == Id);
HttpResponseMessage response;
if (u != null)
response = Request.CreateResponse(HttpStatusCode.OK, u);
else
response = Request.CreateResponse(HttpStatusCode.NotFound);
return response;
}
[Route("~/api/user/login")]
public HttpResponseMessage Post([FromBody]User Source)
{
User requestedUser = db.Users.Single(x => x.EmailAddress == Source.EmailAddress);
HttpResponseMessage response;
if (requestedUser != null && Hashing.ValidatePassword(Source.Password, requestedUser.Password))
response = Request.CreateResponse(HttpStatusCode.OK, requestedUser);
else
response = Request.CreateResponse(HttpStatusCode.NotFound);
return response;
}
public HttpResponseMessage Post([FromBody]User Source)
{
try
{
User u = new User();
u.CreatedBy = Source.CreatedBy;
u.CreatedOn = Source.CreatedOn;
u.EmailAddress = Source.EmailAddress;
u.FirstName = Source.FirstName;
u.LastName = Source.LastName;
u.ModifiedBy = Source.ModifiedBy;
u.ModifiedOn = Source.ModifiedOn;
u.Password = Source.Password;
u.RoleId = Source.RoleId;
u.Role = db.Roles.Single(x => x.Id == u.RoleId);
db.Users.Add(u);
db.SaveChanges();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}
catch (Exception ex)
{
return ThrowError(ex, "POST USER");
}
}
public HttpResponseMessage Put(int id, [FromBody]User Source)
{
try
{
User existing = db.Users.Single(x => x.Id == Source.Id);
if (existing != null)
{
existing.CreatedBy = Source.CreatedBy;
existing.CreatedOn = Source.CreatedOn;
existing.EmailAddress = Source.EmailAddress;
existing.FirstName = Source.FirstName;
existing.LastName = Source.LastName;
existing.ModifiedBy = Source.ModifiedBy;
existing.ModifiedOn = Source.ModifiedOn;
existing.Password = Source.Password;
existing.RoleId = Source.RoleId;
existing.Role = db.Roles.Single(x => x.Id == existing.RoleId);
db.Entry(existing).State = System.Data.Entity.EntityState.Modified;
db.SaveChanges();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent("Success", Encoding.Unicode);
return response;
}
else
{
return ThrowError(new ArgumentNullException("No user record found"), "UPDATE USER");
}
}
catch (Exception ex)
{
return ThrowError(ex, "UPDATE USER");
}
}
public HttpResponseMessage Delete(int id)
{
User user = db.Users.Find(id);
HttpResponseMessage response;
if (user == null)
{
response = Request.CreateResponse(HttpStatusCode.NotFound);
}
else
{
db.Users.Remove(user);
db.SaveChanges();
response = Request.CreateResponse(HttpStatusCode.OK);
}
return response;
}
private HttpResponseMessage ThrowError(Exception ex, string Action = "")
{
StringBuilder sb = new StringBuilder();
sb.AppendLine(String.Format("Error actioning request: [ {0} ]", ex.Message));
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.BadRequest, "Error");
response.Content = new StringContent(ex.ToString(), Encoding.Unicode);
return response;
}
}
Here's the controller on the client (MVC) website that uses the above:
public class UserController : Controller
{
// GET: User
public async Task<ActionResult> Index()
{
List<User> users = new List<User>();
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://www.ortund.com/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.GetAsync("api/user/");
if (response.IsSuccessStatusCode)
{
users = await response.Content.ReadAsAsync<List<User>>();
}
}
return View(users);
}
[HttpPost]
public async Task<ActionResult> Create(User source)
{
if (ModelState.IsValid)
{
try
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://www.ortund.com/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.PostAsJsonAsync("api/user", source);
if (response.IsSuccessStatusCode)
{
return Json(new
{
Message = "Success",
IsOK = bool.TrueString
});
}
}
return View();
}
catch(Exception ex)
{
ThrowError(ex, "CREATE");
}
}
return View();
}
[HttpPost]
public async Task<ActionResult> Edit(User source)
{
if (ModelState.IsValid)
{
try
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://www.ortund.com/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.GetAsync(String.Format("api/user/{0}", source.Id));
if (response.IsSuccessStatusCode)
{
Uri ppUrl = response.Headers.Location;
// HTTP PUT
User user = await response.Content.ReadAsAsync<User>();
user.EmailAddress = source.EmailAddress;
user.FirstName = source.FirstName;
user.LastName = source.LastName;
user.ModifiedBy = String.Format("{0} {1}", Request.Cookies["ortundAdmin"]["fname"], Request.Cookies["ortundAdmin"]["lname"]);
user.ModifiedOn = DateTime.Now;
user.Password = source.Password;
response = await client.PutAsJsonAsync(ppUrl.ToString(), user);
return Json(new
{
Message = "Success",
IsOK = bool.TrueString
});
}
}
return View(source);
}
catch (Exception ex)
{
ThrowError(ex, "EDIT");
}
}
return View(source);
}
private async Task<ActionResult> Delete(int id)
{
string url = String.Format("api/user/{0}", id);
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri("http://www.ortund.com/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.DeleteAsync(url);
return RedirectToAction("Index");
}
}
private ActionResult ThrowError(Exception ex, string Action)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine(String.Format("Error actioning request: [ {0} ]", ex.Message));
return Json(new
{
Title = String.Format("{0} USER", Action),
Message = HttpUtility.HtmlEncode(sb.ToString()),
Error = ex.ToString()
});
}
}