MVC Project and MVC project with API - c#

I have recently started working on MVC application. However my first plan was to create two separate projects in the same solution. One asp.net MVC web application and second is asp.net WebAPI. So that my Web Application will talk to Web API which in return will send JSON response to application which will be converted to View Model for View.
Workflow Diagram :
As i studied more i got to know that API controller and controller both merged into a single controller class in MVC 5. so here is my question how can i achieve the above workflow in MVC 5.
MVC 5 Workflow Diagram
So here comes the problem for me in MVC 5 or i am unable to understand it completely E.g :
UserModel
public class UserModel
{
Public int UserId {get;set;}
Public string Username {get;set;}
}
UserController
[HttpGet()]
public IActionResult GetUser(int id)
{
// do some work
return View(userObject);
}
View
#model UserModel
<h1>#Model.Username</h1>
but when i call the above method from mobile it will give me the rendered html which is not useful for me so do i need to create another method in the same controller in which will return data in JSON.
[HttpGet()]
public IActionResult ApiGetUser(int id)
{
// do some work
return JSONResponse.. ;
}
Modifying method :
[HttpGet()]
public IActionResult GetUser(int id)
{
// calling api get user method
ApiGetUser(int id); // return json
// do some work to convert json into ModelObject
return View(userObject);
}
And if any one mobile app needs data it can call m APIGetUser Method but in this scenario for me its tedious and no of extra methods will be added in the same class. So my basic question is my understanding towards the flow is wrong or am i missing somethings because if below mentioned workflow is right than i would prefer the first one as its separate WebAPI project and easy to maintain ?

In my opinion both diagram are architecturally correct.
But you should consider SRP and separation of concern this: if MVC controller + WebApi controller are both an entry point to your application, running the same code and returning it in 2 different way, they are actually doing 2 different things isn'it? One serve the view and the other one the json.
Plus if you have to render a view there are naturally some behaviuour that isn't common with your web api (cache or rendering partial view for example).
If you think the same, you should leave aside that in MVC 5 both MVC+WebApi controller are under the same class and split it for the reason above.
Hope it helps!

Related

ASP.NET Core 2.2 MVC : wrap responses

I have an application developed in ASP.NET Core MVC with a set of controllers for normal view responses and Web API.
I am trying to figure a correct way to wrap all Web API responses with a consistent class.
My first question is what would be a correct approach to wrap the responses coming from Web API controllers. Since I have two controller types, I would need to distinguish between them as the responses should only be wrapped for API controller, and not view controllers.
As I understand there are two choices a middleware or an action filter.
At first I thought the middleware would be the best choice, but then I realized that I would still need to figure out what kind of request is being processed which would add more potential headache with maintenance?
Then I looked at an action filter and it seems that it would be a better choice to plugin the wrapping handling.
For example an action filter can be added to a base controller just for Web API and not controllers handling the views.
So the question is whether the action filters are best approach to achieve this?
I would recommend you to look at result filters for this. Result filters run after a controller action has produced a result, and it allows you to look at that result and then perform some action.
For example, when you return View in a controller action, then what gets returned is a ViewResult which makes it easy to identify results that would cause a Razor view to be rendered.
Within an API controller, you would usually return a ActionResult<T>, some model object directly, or an ObjectResult. The former two will be automatically converted into an ObjectResult as the action gets executed. So you can just look for ObjectResults and then change the result to have some wrapper object instead. This would look something like this:
public class WrapApiResponseResultFilter : IResultFilter
{
public void OnResultExecuting(ResultExecutingContext context)
{
var result = context.Result;
if (result is ObjectResult)
{
// wrap the inner object
var newValue = new WrapperObject(result.Value);
// replace the result
context.Result = new ObjectResult(newValue)
{
// copy the status code
StatusCode = result.StatusCode,
};
}
}
public void OnResultExecuted(ResultExecutedContext context)
{ }
}

Correct return type from web API

I am creating a c# .net core 2.2 web API for my next project. My question is when returning data should I return the object or IActionResult OK(returnObject)?
The reason I ask is I am using swagger and swagger studio to create my models for an Angular front end. If I return an IActionResult from the API the returned view models are not detailed in the swagger.json file so I would have to code these in the angular application. If I return whatever object is created the model is created in the swagger.json.
What practice should I follow to return data from an API in this case?
You do want to return IActionResult(object) but you are not quite done.
Annotate your controller with the ProducesAttribute and annotate your method with the ProducesResponseTypeAttribute:
[Produces("application/json")]
public class SomethingController
{
[ProducesResponseType(typeof(YourObject), (int)HttpStatusCode.OK)]
public IActionResult GetThing(int id)
{ ... }
}
This allows Swagger UI to know what to expect and document it appropriately. Shown above is for a synchronous method; it works for asynchronous as well.
You can return
- Specific Type
- IActionResult
- ActionResult
For more details, please refer MSDN article at : https://learn.microsoft.com/en-us/aspnet/core/web-api/action-return-types?view=aspnetcore-2.2

Controller hangs when opened using url in mvc 5

I'm new on asp.net mvc. I created a basic controller and I tried to open it using url. But rendering is not finished and my controller didn't display in several minutes. I did not change anything from default asp.net 5 mvc project also my controller's index method return only hello world string. I don't is there any problem on iis or VS. Any idea about that problem?
Thanks for help.
In MVC only public methods that return an ActionResult are accessible as web pages.
So you MUST use something like this:
public class HelloWorldController : Controller
{
// GET: HelloWorld/Index
public ActionResult Index()
{
return Content("This is <b>Index</b> action...");
}
// etc
}
Content(...) is a special method the wraps text into an ActionResult.
Note: only use Content(...) if you specifically do NOT want to use a View such as Index.cshtml - which is what you normally WOULD do, of course.

How we can create 3 tier architecture in ASP.Net MVC application with EF?

I am creating a new project (web application) in ASP.NET MVC 5 with Entity framework 6. I have worked in 3 tier architecture with ASP.Net web form application but i am confusing to deal with entity framework, models etc.
So, how can i build 3 tier architecture in MVC with EF and it is feasible to use with entity framework ?
Yes you can implement a 3/N tier architecture (or something similar).
ASP.NET MVC has a great collaboration with entity framework. EF even is installed and used for users/roles management (identity) in default ASP.NET MVC template.
A typical ASP.NET MVC application consists of Models, Views and Controllers. Briefly:
Models are POCOs. The model encapsulate data and it's responsible for data validity. For analogy - this is a part of application tier and a part of data tier. The data tier include also EF db context class.
Views are .cshtml files which produce html and can be strongly typed (have model). For analogy - This is the presentation tier.
Controllers are responsible for processing of HTTP requests, retrieving data model and passing the model to the view. For analogy - This is a part of application tier (business logic).
Typically the controller will receive some viewModel, validate it, process it, and return some action result (view, partial view, JSON, file, etc.). In the process part the controller can initialize entity framework context, and gets or save data to database through the EF db context etc.
It's almost always a good idea to "keep the controller as thin as possible", so many ASP.NET MVC solutions use repository/Unit of Work or service pattern.
Example for some typical part of MVC application for creating some entity using services:
Services
// Connect to database through entity framework db context.
public interface IMyService
{
MyDbContext DbContext { get; set; }
IQueryable<Something> GetSomething( ... query params ... );
void CreateSomething(Something model);
// etc.
}
Controller
public MyController
{
private IMyService myService;
public MyController(IMyService myService)
{
this.myService = myService;
}
// Showing create/edit form
[HttpGet]
public ActionResult CreateSomething()
{
// Create Empty view model. new SomeViewModel(); for example.
// Get some nomenclatures for dropdowns etc. through the service (if needed).
// return View(viewModel);
}
// Processing the post request
[HttpPost]
public ActionResult CreateSomething(SomeViewModel viewModel)
{
// Check validity of viewModel (ModelState.IsValid)
// If not valid return View(viewModel) for showing validation errors
// If valid map the viewModel to Model (through AutoMapper or custom mapping)
// Call myService CreateSomething method.
// Redirect to page with details.
}
}
Model
public class Something
{
public int Id { get; set; }
public string Name { get; set; }
// .. more properties (can be decorated with validation attributes)
}
Presentation View Models
// View model for Something class. Including only properties related to the current UI.
public class SomeViewModel
{
public int Id { get; set; }
// .. more properties (can be decorated with validation attributes)
}
View
#model SomeViewModel
<!-- Form -->
#Html.ValidationForModel()
#Html.EditorForModel()
submit button
<!-- /Form -->
Yes you can implement a 3 tier architectur:
Tier (Presentation): Views (this is what the V stands for in MVC
Tier (Logic): Usually the Models and some Helperclasses (this is what the M stand for)
Tier (Data): Whit the help of the Entity Framework you could create a database from your models.
Here's a tutorial on how to use the Entity Framework with ASP.NET MVC.
Here is how you can implement 3-Tier:
Presentation layer include (MVC)
Business Logic Layer will include (C# programming - a dll)
Data access layer will include (C# programming with entity frameworkor- a dll) Business Object Layer will include (Entity Framework models)
Ref: http://www.codeproject.com/Articles/841324/ASP-NET-MVC-Web-App-on-Tier-for-Beginners

Provide API with asp.net MVC Web Application

I currently have a MVC 3 Web Application with around 50 Views.
Is it somehow possible to provide some kind of API next to my Views so everything still works fine and dandy?
My kinda perfect world idea:
Server is running and every request gets to its view. The user can decide in his get request if he wants the raw data in lets say JSON. Additional to the raw data also the Structure/Names of the Viewmodel will be parsed so the Modelbinder can do his stuff.
or another approach might be to somehow deactivate my Views to have only the API available (again with raw data and structure).
Is this even possible (the modelbinder is kinda a big concern) and maybe even without much effort/trouble to do?
If you don't want to do everything all over again with WebAPI, you can implement some ActionFilterAttribute to change the ActionResult based on some querystring f.i.
Something like this:
public class ResultSwitcherAttribute: ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.HttpContext.Request["data"] != null && filterContext.HttpContext.Request["data"] == "json")
{
filterContext.Result = new JsonResult
{
Data = (filterContext.Result as ViewResult).Model,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}
}
Then, you'll register that either in application_start or per controller/action like this:
[ResultSwitcherAttribute]
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new TestModel()
{
Web = "http://www.mywebpage.com", Name = "Yngve"
});
}
}
When you now access your url with ?data=json you'll get a JSON-representation of the Model, instead of the view.
EDIT: Code sample updated
Consider adding an ASP.NET Web API to your app. It's extremely simple to implement, entailing little more than adding an API controller with methods corresponding to your REST actions. I don't know how one would go about adding this to an MVC 3 app, but I have a recipe for MVC 4 Internet Applications in this stackoverflow question. So, if you're fine with upgrading your project so that it is Web API capable, perhaps to MVC 4, I think it'd represent a good alternative.
To learn ASP.NET Web API, this tutorial is a good place to start.

Categories