I'm working on my first Asp.Net Core project, which is to support both a web client, and a Game client (written in Unity).
Now, I started with the default Asp.Net Core Web Application project template provided by Visual Studio 2015, including authentication for Individual User Accounts.
Most, if not all of the generated controllers are returning views, following this pattern in general:
[HttpGet]
[AllowAnonymous]
public IActionResult Get()
{
//Do something smart
return View();
}
This method returns a View as you can see and all is good when requested by the web client.
But what if the Game is sending a request to the same method?
In that case a JSON response is expected (not a View/html document), and my question is what is the recommended "pattern" for supporting this in Asp.Net Core?
Should I place the api returning JSON in separate controllers, hence duplicating some logic? It doesn't feel right to me...
Or should I check the request for an expected response format, and implement logic for returning different responses based on this?
I don't particularly like that approach either...
To me, it seems Asp.Net Core messes things up by providing UI formatted responses directly from the API, but it might be something I've missed here...
Any pointers?
You could move the logic into a class to be called by the controller if you want separate controllers or actions for the Webpage and game.
This would be better and follow the single responsibility rule rather than one action returning two response types
When the return type is IActionResult you can also return Json messages for example as return Json(myReturnObject). You can add an if to return a JSON message and when it is false it will return the view.
You can add an if based on X-Requested-With:
if (Request.Headers["X-Requested-With"] == "XMLHttpRequest")
{
return Json(myObject);
}
What I would recommend is to split the requests in different controller methods by response type and add the shared code/logic in a private method or to another class, probably you will use this elsewhere too. By doing this you will be able to do proper tests and won't get confused when it will return the view or a json message.
Hope this helps.
Related
In my work I was asked to implement health checks into an ASP.NET Web API 2 written in C#. I have searched but all the documentation is for ASP.NET Core and its implementation, does anyone know how to implement health check featurs in the classic / full .NET Framework?
I agree with Igor. Here's a concrete application of what he suggested (obviously, there are other ways to do this, but this is the best way I know how to keep it clear and honor separation of concerns):
Create a new controller. In this example, I'll call it HealthController
Add an action to the controller, and annotate it with [HttpGet]
Place logic inside the action that checks for the stability of external dependencies. For example, if disk access is critical for your API, run a test or two to make sure that the disk is responding like you need it to. If you need to be able to query a database, make a sample query, and make sure it's successful. This part is completely custom and really depends on your API and how it needs to perform.
public class HealthController : ApiController
{
[HttpGet]
public IHttpActionResult Check()
{
// Add logic here to check dependencies
if (/* successful */)
{
return Ok();
}
return InternalServerError(); // Or whatever other HTTP status code is appropriate
}
}
Have an external service issue a GET request to your endpoint (currently at https://whatever.your.domain.is/Health/Check) and report back when it doesn't receive 200 OK for some amount of time.
I've used Amazon CloudWatch in the past and I've been happy with it. There are going to be other services out there that will do this for you, but I don't have any experience with them.
I want a controller like
public ActionResult UnlockAssets ( string psd )
{
// ...
}
that external sites can call and have JSON returned from. Is this possible? If so, where do I start?
You probably want a Web API (http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api)
Heres a simple example
using System;
using System.Linq;
using System.Net;
using System.Web.Http;
public class DocumentsController : ApiController
{
public IHttpActionResult UnlockAssets (string psd )
{
var documents = new DocumentRepo();
if (!documents.Exists(psd))
{
return NotFound();
}else{
documents.unlock(psd)
return Ok(product);
}
}
}
Yes it is possible the external site would call your controller via Ajax for example.
The external site would have a Javascript function with Ajax that would call the url:
http://www.yourwebsite.com/yourcontrollername/UnlockAssets?psd=value
Your response can be JSON, you could use the ActionResult signature and return JSON but formatting might be off and the header response header might be incorrect, by NOT saying you have a JSON response to the requester/client.
So this would be the correct ASP.NET MVC signature method for your controller
[HttpGet] //or [HttpPost] or both
public JsonResult UnlockAssets ( string psd )
{
return Json(new { foo = "blah"});
//or
return Json(someinstanceofaclassofyours);
}
You do not need Web API as someone suggested, you might prefer Web API but really it just depends on what is right for you, your timelines, what your clients need when they call your server etc, the complexity of your architecture, the complexity of the clients' needs.
A normal ASP.NET MVC Application Controller can act as an "API" in simple architecture (even a complex) one and serve the needs of external clients just fine. That controller can server Views for your ASP.NET MVC site as well as return JSON to an external caller. If that Controller seems like the right way to organize your architecture than fine.
When making architectural decisions you may consider Web API more appropriate when you are building an actual API for clients to consume, this API would have documentation, expose various methods for client callers, be robust. Web API can also be used for simple method for clients to call. There is no right or wrong choice it is more just a the right tool for the job.
I would say, if you have Models, Entity Framework interwoven in an ASP.NET MVC Application already, and you just have a method you are trying to expose to an external client, you don't see your MVC Application growing quickly and getting out of hand, just use a controller. Otherwise use Web API either by adding Web API to your existing MVC project or preferably adding a new Web API project to your solution.
I am currently following this tutorial to create a simple REST service using Web Api. Note this is my first time doing something like this and I am just trying to learn more.
http://www.asp.net/web-api/overview/creating-web-apis/creating-a-web-api-that-supports-crud-operations
I have followed all the instructions and have it successfully running on my localhost. I understand that in this tutorial the URI for all my GET requests look something like:
localhostapi/products/id
And I understand that, and how to perform simple GET requests in the URI and see it actually occuring using my developer tools in my browser.
Now my question is... How do I make POST/DELETE/PUT requests and actually see what they are doing? The guide wasn't too clear, do I pass in parameters into the URI? Does the URI change when I want anything but a GET request? This text here seems to explain it but I do not understand:
The method takes a parameter of type Product. In Web API, parameters with complex types are deserialized from the request body. Therefore, we expect the client to send a serialized representation of a product object, in either XML or JSON format.
It's quite easy to make POST, PUT, DELETE requests. You just need to install Fiddler at http://www.telerik.com/download/fiddler
Next, install and run it. Go to the Composer tab on the right hand side. Next, put your local host URL, and the request method, and other data like the screenshot below
You can write unit tests, like
[TestMethod]
public void GetAllProducts_ShouldReturnAllProducts()
{
var testProducts = GetTestProducts();
var controller = new SimpleProductController(testProducts);
var result = controller.GetAllProducts() as List<Product>;
Assert.AreEqual(testProducts.Count, result.Count);
}
This link also This one may help.
more:
How to call ASP .NET MVC WebAPI 2 method properly
Sending C# object to webapi controller
You can set a breakpoint on your controller methods that handle the post/delete/put.
Same thing in your browser at the point where you call the post/delete/put (presumably in a jquery request)
You can also unit test your controller methods:
http://www.asp.net/mvc/tutorials/older-versions/unit-testing/creating-unit-tests-for-asp-net-mvc-applications-cs
In our application, which is Single Page application, we are using MVC controller(Action methods as API) for CRUD operation's. Which I feel its wrong.
Can someone tell me if its correct?
Eg:-
I have an API Controller say :-
public class MockAPIController : ApiController
{
// GET api/MockAPI/5
public ClassA GetSomething(int id)
{
return new ClassA();
}
}
and this can be called from client-side using /api/MockAPI/GetSomething/1. Similarly if I create MVC Controller like:-
public class MockAPIController : Controller
{
// GET api/MockAPI/5
public ActionResult GetSomething(int id)
{
return new JsonResult(new ClassA(),JsonRequestBehavior.AllowGet);
}
}
Still, I can get it work. Can some-one tell me whats demerit of using MVC controller for API?
EDIT:-
Is it recommended to use MVC Controller for API methods?? If Not, then can someone point out the -ve aspect of it?
Using the web API you can return objects as normal and your clients can specify the content-type.
This will automatically serialize the objects to xml or json without the need to specify a new action just to change the return type.
So your API call will always remain as:
public ClassA GetSomething(int id)
{
return new ClassA();
}
But it is capable of returning xml and json without any changes in the controller.
Web API provides cleaner way to craft your HTTP responses. It is extremely extensible, testable and faithful to the HTTP spec.
Web API was NEVER intended to provide an "out-of-the-box" REST framework.
MVC is a HTTP framework, optimized for serving content to a Web Browser. Web API has no bias as to what client is using it.
As per my understanding,
MVC controllers are extended over API Controller. You can do almost
everything what can be done with API Controller.
(People please correct me if I am wrong, its purely my understanding which I am sharing!)
Now, if your application is a web based application/internet or intranet where you have very few api call's then you can stick with MVC Controllers. Only care that need to be taken care is sending data as JsonResult(basically serializing`to JSON or whatever). If you have more funda of SPA, the API controllers is what you need.
I myself have not found much articles stating a strong line separating what to use when, it's always a developers pain to decide and implement.
It's less about merit and demerit of using ApiControllers in place of Controllers, and more about implementation and usage.
ApiControllers are specifically meant for building REST-ful Apis which return serialized data to the client in simplest form.
And, using controllers you can return Views, Different Types of ActionResults in different form. You can definitely convert the type of data you are returning, like the way you are using here but it's not the same with ApiControllers.
I am creating a RESTful webservice using ASP.NET MVC (not ASP.NET Web API). What I want to do is have every method in the controller return their result based on an input parameter (i.e. json or xml).
If I were using ASP.NET Web API, the HttpResponseMessage works for this purpose. When I attempt to return an HttpResponseMessage from a controller in ASP.NET MVC, there is no detail.
I have read that in this approach, I am supposed to use ActionResult. If I do this, then I need to create an XmlResult that inherits from ActionResult since it is not supported.
My question is why HttpResponseMessage does not work the same in both situations. I understand that in Web API, we inherit from ApiController and in ASP.NET MVC we inherit from System.Web.Mvc.Controller.
Any help is greatly appreciated.
Thanks,
EDIT 1
Much thanks to Fals for his input. My problem was in how to create an empty website and add all of the necessary functionality in. The solution was to use Nuget to get the packages mentioned in the comments and then to follow the steps in How to integrate asp.net mvc to Web Site Project.
Web Api is a Framework to develop Restfull services, based on HTTP. This framework was separeted into another assembly System.Web.Http, so you can host it everywhere, not only in IIS. Web API works directly with HTTP Request / Response, then every controller inherit from IHttpController.
Getting Started with ASP.NET Web API
MVC has It's implementation on System.Web.Mvc. coupled with the ASP.NET Framework, then you must use It inside an Web Application. Every MVC controller inherits from IController that makes an abstraction layer between you and the real HttpRequest.
You can still access the request using HttpContext.Response directly in your MVC controller, or as you said, inheriting a new ActionResult to do the job, for example:
public class NotFoundActionResult : ActionResult
{
private string _viewName;
public NotFoundActionResult()
{
}
public NotFoundActionResult(string viewName)
{
_viewName = viewName;
}
public override void ExecuteResult(ControllerContext context)
{
context.HttpContext.Response.StatusCode = 404;
context.HttpContext.Response.TrySkipIisCustomErrors = true;
new ViewResult { ViewName = string.IsNullOrEmpty(_viewName) ? "Error" : _viewName}.ExecuteResult(context);
}
}
This ActionResult has the meaning of respond thought HTTP Error.
As a matter of fact, it is indeed possible. You basically have two options:
develop your custom ActionResult types, which can be an heavy-lifting work and also quite hard to mantain.
add WebAPI support to your website.
I suggest you to do the latter, so you will have the best of two worlds. To do that, you should do the following:
Install the following Web API packages using NuGet: Microsoft.AspNet.WebApi.Core and Microsoft.AspNet.WebApi.WebHost.
Add one or more ApiControllers to your /Controllers/ folder.
Add a WebApiConfig.cs file to your /App_Config/ folder where you can define your Web API routing scheme and also register that class within Global.asax.cs (or Startup.cs) file.
The whole procedure is fully explained here: the various steps, together with their pros-cons and various alternatives you can take depending on your specific scenario, are documented in this post on my blog.