Asp.Net MVC with Web Api - asp.net

I am looking for a good approach for implementing intranet Web Application using Web Api(2) with Asp.net MVC(5).
Application is designed in such a way that we use AngularJS SPA at client side and in server side MVC with Web Api as a single application/web site. MVC is because we have to restrict the operations based on the security permissions. We don't render the action buttons(eg. Save, Delete etc) when we call MVC controller for views if the user does not have permission. Other operations are utilizing Web API methods to Save, Delete etc,
Basic idea is
MVC Controllers are for generating views with action buttons removed if the user doesn't have permission(html templates for AngularJS).
Data Manipulation is through Web API(AngularJS $http service web api calls)
Questions here
How do we derive an authentication mechanism which we can utilize for both MVC and Web API?
(We can create Authentication filters but we have to create separate filters for MVC and Web API, right?)
Once the user is authenticated how do we share this info with both MVC Controller and Web Api controller instead of validating the user each request from angular js?
Is it possible to use ASP.Net forms authentication for both MVC and WebApi for authentication?. If so how do we do that?. Will forms authetication token validates for both MVC controller and Web Api controllers automatically using [authorize] attribute?
Also I would like to know, is it a good approach mixing MVC with WebApi with in a single application?

Its a feasible option but not a recommended option.
Since WebApi operation will be inheriting from ApiController
and MVC controller action will be inheriting from Controller Class.
If you want to define route for api and mvc controller then you need to register the route like this in Global.ascx in
Application start
GlobalConfiguration.Configure(WebApiConfig.Register);
RouteConfig.RegisterRoutes(RouteTable.Routes);
RouteConfig Class
public static class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
.....
....
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
WebApiConfig Class
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// TODO: Add any additional configuration code.
// Web API routes
config.MapHttpAttributeRoutes();
config.Formatters.XmlFormatter.UseXmlSerializer = true;
config.MessageHandlers.Add(new YourMessageHandlers());
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}

Related

what is the best way to consume web api in mvc

I am using web api in my mvc application. I have method in web api which returns user detail using userId (which is in session["userID"])
public object getUserDetail()
{
//here is need of session["userID"]
// return somthing
}
so what is best way to access this web api method from jquery . Should i access this directly or first i should call my controller method and from there i should call this web api method.
You can directly call WebApi from jquery for performing operations(like insert/update/delete)other than returning JSON for processing back. For the scenarios where you require manipulating your view, call mvc controller which calls the Webapi.
So, for your case, the getUserDetail() method returns data. If these return values needs to be used in your view, then call it from mvc controller
WebApi is already an exposed endpoint for you to access your data from. Going to your controller, and calling the method from there diminishes the intent of having exposed the method as an Api in the first place. Try making a call to the route of the Api method, and you should be fine.
On a side note, try exposing a strongly typed object instead of just returning an object.
what is best way to access this web api method from jquery
Simply make an ajax call.
var url = www.example.com/api/user;
$.ajax({
type: 'GET',
url: url,
success: function(userValue) {
// Do something with your user info...
},
error: function(error) {
// Something went wrong. Handle error.
}
});
And have your controller return the value.
public class UserController : ApiController
{
[HttpGet] // For clarity only
public object Get()
{
// return your object.
return session["userID"];
}
}
And to get your url for the controller, you can use this in your view.
Url.HttpRouteUrl("DefaultApi", new {controller = "UserController "})})
Where DefaultApi is the route name defined in your route table (usually in RouteConfig.cs).
Edit:
Regarding access to session there's a number of ways to get around it. Take a look at this question and I think you will solve it. Accessing Session Using ASP.NET Web API
Or this tutorial:
http://www.codeproject.com/Tips/513522/Providing-session-state-in-ASP-NET-WebAPI
public class SessionableControllerHandler : HttpControllerHandler, IRequiresSessionState
{
public SessionableControllerHandler(RouteData routeData)
: base(routeData)
{}
}
public class SessionStateRouteHandler : IRouteHandler
{
IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext)
{
return new SessionableControllerHandler(requestContext.RouteData);
}
}
And lastly register it with your route:
RouteTable.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
).RouteHandler = new SessionStateRouteHandler();
Or add this to your Global.asax.cs
protected void Application_PostAuthorizeRequest()
{
System.Web.HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
}
Feels like you might want to step back and rethink the basics. The main question here is: does it sound right that one view layer (MVC) calls another view layer (web api)? And simple answer is: no.
Usual setup is that your ajax calls target your Web Api controller methods directly. But if for whatever reason you find yourself thinking that you really need your MVC to call WebApi then that looks for extracting business logic to separate layer/tier so what you end up with is both, MVC and Web API, calling same method in separate class/layer (whatever your methods actually do).
So, instead of:
//this is in your MVC controller
public ActionResult SomeMVCAction(){
MyWebApiMethod();
}
//This is in your web api controller
public SomeStrongType MyWebApiMethod(){
var sum = 2+2;
}
you might want to have something like:
//this is in your MVC controller
public ActionResult SomeMVCAction(){
DoSum();
}
//This is in your web api controller
public SomeStrongType MyWebApiMethod(){
DoSum()
}
///This function is defined in separate layer/project which is your business layer
public static int DoSum(){
return 2+2;
}
PS.
Regarding session...There is a reason why session is not (easily) accessible in WebApi. REST Api should be stateless so you might want to rethink your design where you need session in web api controller.
You can describe a problem you're trying to solve by accessing session in web api controller and then we can try to give opinion on that.

Trying to display Custom View in MVC app but it says requested URL not found

I am new to azure, MVC and also ASP.NET. I am writing MVC Cloud service with ASP.NET web role. Please help me with this problem
When I create the application there are default views but I wanted to see my view so I set my view as start page. I also changed the values in RegisterRoutes method
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "User", action = "AddUser", id = UrlParameter.Optional }
);
}
When I run the app, it gives HTTP 404 error because it could not find request URL : /Views/User/AddUser.cshtml
In MVC you don't put the view in the URL to get it rendered.
This won't work: /Views/User/AddUser.cshtml
As you've correctly put in your question the default route is {controller}/{action}/{id} with id being optional.
So assuming that User is your controller, i.e. you have a class called UserController, which looks something like:
namespace My.Controllers
{
public class UserController : Controller
{
which has an action on it called AddUser:
public ActionResult AddUser()
{
// implementation logic
return View();
}
Then the default route will display your view when it processes the URL /User/AddUser
In MVC 5, this looks something like:

Routing in a hybrid app that is classic ASP.Net web forms and MVC

i have inherited an application that is both clasic asp.net web forms and mvc (started as web forms project). I would like to setup routing like MVC. What is the best way to go here? All i need is a push in the right direction.
I know how to setup routing for the MVC only project via global.asa > App_Start > Route Config and area registration cs files.
Environment:
VS 2012, IIS 7, ASP.NET 4.0, classic asp.net web forms and MVC 4.
My thinking:
I am thinking about doing some thing like following, do you guys see an issue here? I may end up with some web.config issues but at this this time i am not sure what those would be. I need your advice to properly setup the structure here.
Global file addition:
protected void Application_Start()
{
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
App_Start > RouteConfig.cs
namespace My.Site
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new string[] { "My.Site.Controllers" }
);
OTHER ROUTES WILL GO HERE, THESE MAY REDIRECT TO a webform page or to a controller action.
}
}
}
Going through the following to setup all properly.
http://www.hanselman.com/blog/PlugInHybridsASPNETWebFormsAndASPMVCAndASPNETDynamicDataSideBySide.aspx
http://www.hanselman.com/blog/IntegratingASPNETMVC3IntoExistingUpgradedASPNET4WebFormsApplications.aspx
http://www.packtpub.com/article/mixing-aspnet-webforms-and-aspnet-mvc
http://msdn.microsoft.com/en-us/library/dd329551.ASPX

Can you use the attribute-based routing of WebApi 2 with WebForms?

As the title states, I'm wondering if you can use the attribute-based routing of WebAPI 2 with WebForms. I feel like this can obviously be done given you can use WebAPI2 just fine in a WebForms application... I just can't figure out how to enable attribute-based routing.
Based on this article, I understand you normally enable it via a call to MapHttpAttributeRoutes() prior to setting up your convention-based routes. But I'm guessing this is the MVC way - I need to know the equivalent for WebForms.
I currently use MapHttpRoute() to set up my convention-based routes, and I'd like to try out the attribute-based routing in WebAPI2. I have updated my project with WebAPI2 - I just need to know how to enable the attribute-based routing feature.
Any info would be appreciated.
You need not do anything special in case of WebForms. Web API attribute routing should work just as in MVC.
If you are using VS 2013, you can test this easily by create a project using "Web Forms" template and then choose "Web API" check box and you should see all the following code generated by this.
WebApiConfig.cs
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Global.asax
public class Global : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
GlobalConfiguration.Configure(WebApiConfig.Register);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
WebForm's RouteConfig
public static class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
var settings = new FriendlyUrlSettings();
settings.AutoRedirectMode = RedirectMode.Permanent;
routes.EnableFriendlyUrls(settings);
}
}

Receiving 404 error when trying to get to MVC application in local IIS

I have an existing web site setup on my local IIS built with web forms setup in this format:
-MainSite
-Application1
-Application2
-Application3
There are separate applications in each location, so MainSite has an application, and Application1 has another application and so on. This way development on different applications in the same site can be broken out. I want to add a new Application that is MVC instead of web forms. I created a new MVC project which runs in Cassini just fine, but when I create a new IIS application for it and point it to the MVC project I am unable to navigate to it in the browser and get a 404 error. I am expecting to be able to navigate to http://MainSite/NewMVCApplication/. I want the root of NewMVCApplication to point to my Contacts Controller.
My global.asax in the new MVC application currently looks like this:
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Root", // Route name
"", // URL with parameters
new { controller = "Contacts", action = "Index", id = "" } // Parameter defaults
);
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
RouteDebug.RouteDebugger.RewriteRoutesForTesting(RouteTable.Routes);
}
}
Make sure NewMVCApplication is running in an integratedMode pipeline application pool.

Resources