How to host WCF Data Service in ASP.Net MVC3 app - c#

I have written several WCF data services and find them quite useful. However, I have found routing to be quite a pain. I have seen conversations that indicate that you can host a data service in an ASP.Net MVC app (I have always used ASP.Net web sites). However, I do not seem to be able to find any examples of how to achieve this. Does anybody have any references I could check-out or advice?

The question was posted some time ago but I assume there are still people interested in using WCF Data Services in ASP.NET MVC projects.
Assuming that you have in your project a service called: 'DataSourceService.svc' you can use this service in an MVC project by configuring the routing in 'RouteConfig.cs' as follows:
using System.Data.Services;
using System.ServiceModel.Activation;
using System.Web.Mvc;
using System.Web.Routing;
namespace <YourNamespace>
{
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 },
// the controller should NOT contain "DataSourceService"
constraints: new { controller = "^((?!(DataSourceService)).)*$" }
);
routes.Add(new ServiceRoute("DataSourceService", new DataServiceHostFactory(), typeof(DataSourceService)));
}
}
}
Make sure that you have in Web.config the following configuration:
<configuration>
...
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
...
</configuration>
Now you can check that everything works fine by running your project in the browser and using the following url:
http://localhost:port_number/DataSourceService/$metadata
... which should return your metadata.

The WCF web api may do what you're looking for. Here's their getting started page. You host the service inside of the MVC app, and even hook into into the same routing that MVC uses.

Related

ASP.NET WebAPI methods working only local but not on WebServer

I created a WebAPI and all routes and methods work perfectly locally:
WebAPI Local
The problem is when I put it on my web server(The local and web tests are on the same server, so the connection string to the database is correct.).
The standard website and standard methods work normally, but the ones I created don't work(500 Internal Server Error):
WebAPI Server Web
WebAPI Server Web Default Methods
WebApi Server Web Default WebSIte
How can it work perfectly local and not web? since nothing has changed in the code?
The error is as if the url did not exist.
These are the code for the web api method and the RouteConfig file
[Route("WebApi/Users/GetAll")]
[HttpGet]
public IEnumerable<User> GetAll()
{
return _userRep.All;
}
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 }
);
}
UPDATE: Looking in the windows application event logs, I noticed several errors related to localdb. I don't know why it didn't work with LocalDB. As my server is also a domain controller, I had problems getting the SQL server installed but I managed with this tutorial: http://lexisnexis.custhelp.com/app/answers/answer_view/a_id/1089877/~/installing-sql-on -a-domain-controller
After that I pointed to the SQLServe instance instead of LocalDB and it worked.
you need to provide more information about your controller
place this on the controller if not present
[Route("api/[controller]")]

Unable to use MVC Controller with ASP.Net Web API 2

What I have so far (that works)
I have an ASP.Net Web API 2 project. Well, at least that's what I remember creating when I set up the project, I am not sure how to confirm that.
I am using Visual Studio 2017, and .Net Framework version 4.6.
In terms of the API side of things, this is all working great. The API controllers are fine, I can get data, post data, etc.
Just a bit of additional information in case it matters, I have added SignalR to the project which has been configured.
As it may be important, here are my various configuration files:
Global.asax.cs
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
RouteConfig.cs
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { action = "Index", id = UrlParameter.Optional }
);
}
WebApiConfig.cs
public static void Register(HttpConfiguration config)
{
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
What I am trying to do (that doesn't work)
However, I want to add a HTML page so the user can view some information (just static HTML stuff, nothing special). So I have created a standard MVC controller with an action like so (and the Index.cshtml view is in the correct Views folder):
public class NotificationsController : Controller
{
public ActionResult Index()
{
return View();
}
}
The problem is that this action never gets run (I have a breakpoint).
What I have tried to identify the problem
Now I get at this point, it could be loads of different things, so here is what I have tried so far to debug the issue:
When I access the URL in a browser (e.g. http://localhost:59461/Notifications), I get:
localhost is currently unable to handle this request.
HTTP ERROR 500
At first I thought maybe this is a routing issue, however in VS 2017 you can see that a request has failed for this action:
So surely the routing must be working correctly? Unfortunately, clicking the requests only confirms the 500 error and doesn't give any more information about the problem.
The only additional information I can find is in the Windows Event Viewer, in which I get the following error:
Application 'MACHINE/WEBROOT/APPHOST/PROJECTNAME' with physical root 'C:\PATH TO PROJECT FOLDER\' failed to start process with commandline '%LAUNCHER_PATH% %LAUNCHER_ARGS%', ErrorCode = '0x80070002 : 0.
But I have researched that error a lot and am yet to find a suitable solution or explanation for my problem.
I have also tried adding Application_Error but that isn't throwing any exceptions either.
At this point I don't know how to work out the cause of the problem. The only thing I can think of is that I need to configure something specifically to allow Web API projects to work with MVC controllers, but I can't find anything on that either.
What can I do to debug this problem correctly, and find the cause?
Urgh... so I solved the problem...
After stumbling across this post, there is a suggestion to delete the .vs folder in the Visual Studio solution folder. After doing this, and rebuilding the solution, it started working.
No idea what is in that folder that causes this problem exactly though, maybe something got corrupted or some sort of caching conflict, who knows...

How do I create pages in a web api project?

I want to display a default status page for my web api project (where instead some IIS message is displayed when I start the project). However it seems like I cannot create views in web api (there is no support for ActionResult).
In addition to a status page I will also use this information to create an api documentation page.
How can I achieve displaying html pages in this situation ?
If your default status page is static html, you don't have to use MVC. Just tell WebApi in your Startup.cs that you want to support static resources:
app.UseFileServer();
For creating an API documentation, maybe you could write that file on startup dynamically?
You can create regular controllers and views in a webAPI project the same as any MVC project. Just create a normal controller that does not inherit from ApiController. In your startup.cs make sure to configure at least a default route.
configuration.Routes.MapHttpRoute(
name: "someName",
routeTemplate: "{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Right click and select Add, then you should see controller at the top. Select one of the mvc controllers.

Azure Mobile App - Getting 405 (Method Not Allowed) when trying POST

I'm trying to migrate my Azure Mobile Service .NET backend to an Azure Mobile App.
I was using some custom Web Api controllers, and after migration I'm getting a 405 (Method Not Allowed) / The requested resource does not support http method 'POST'. error when trying to POST to a controller method that worked before.
I spent hours trying diffent CORS settings but I had no success so far.
This is how I currently configure Web Api:
HttpConfiguration config = new HttpConfiguration();
new MobileAppConfiguration()
.UseDefaultConfiguration()
.ApplyTo(config);
var cors = new EnableCorsAttribute("*", "*","*");
//var cors = new EnableCorsAttribute("*", "*","GET,POST,DELETE,HEAD,PUT,PATCH,OPTIONS");
config.EnableCors(cors);
config.Routes.MapHttpRoute(
name: "Rest",
routeTemplate: "rest/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.MapHttpAttributeRoutes();
The controller looks like that:
[Authorize]
[RoutePrefixAttribute("rest/companies")]
public class CompaniesController : ApiController
{
[HttpPost]
[Route("my-active")]
//[EnableCors("*","*","*")]
public HttpResponseMessage SetActive(/*[FromBody]*/Company company)
{
// Implementation
}
}
What I tried too:
Set CORS settings in web.config (custom headers / different settings), eg. <add name="Access-Control-Allow-Methods" value="GET,POST,DELETE,HEAD,PUT,PATCH,OPTIONS" />
Added a cors message handler according this blog post
(http://blog.bittercoder.com/2012/09/09/cors-and-webapi/)
This handler is also removed: <remove name="OPTIONSVerbHandler" />
One thing I noticed is, that a Azure Mobile App component seems to override the allowed methods and allowed headers that I configured using config.EnableCors(cors). I was only able to control all settings using web.config and the message handler. But it did not solve the 405 problem anyway.
At this point, I'm not sure if it's a CORS problem at all.
Any ideas? It's currently hard to find good documentation on Mobile Apps and I would appreciate if the .NET backend part would be open sourced... It's somewhat of a black box for me.
It could happen when you activate App Service Authorization and forget to change your mobile client url from http to https.
If so, your http Post will be redirected to the https url but with a Get message.
Found it thanks to Fiddler.
OMG, I found the problem with my code. I had to swap this two statements:
// Needs to be called before MapHttpRoute
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "Rest",
routeTemplate: "rest/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
As I was using Azure Mobile Services, calling MapHttpAttributeRoutes caused an error 'An item with the same key has already been added', so I removed that line. I had to re-insert it for Azure Mobile Apps again in order to get attribute routing to work, but I did it at the wrong place, so be careful.
If http Post is redirected to the https url as Get, try calling https directly.
Azure logs looks as follows in this case:
Received request: POST http://xxx.azurewebsites.net/api/Data/test
Information Redirecting: https://xxx.azurewebsites.net/api/Data/test
Received request: GET https://xxx.azurewebsites.net/api/Data/test
in this case call https://xxx.azurewebsites.net/api/Data/test

How to call/reference external web api project in MVC4 project

I am new to Web API & MVC I have created new WEB API & MVC solution separately now i want to refer Web API action method in MVC so for that following code i written,
Web Api Project Side,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Data;
using System.Net.Http;
using System.Web.Http;
using AttributeRouting.Web.Mvc;
using RegisterStudent_WebAPI.Models;
namespace Register_Student_WebAPI.Controllers
{
public class RegisterStudentController : ApiController
{
[Route("api/student")]
[HttpGet]
public IEnumerable<Student> GetStudents()
{
RegisterStudent_API_DB objRegisterStudent = new RegisterStudent_API_DB();
List<Student> lstStudent = objRegisterStudent.GetStudent();
return lstStudent ;
}
} }
WEB.Config File from API,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
namespace RegisterStudent_WebAPI
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// Uncomment the following line of code to enable query support for actions with an IQueryable or IQueryable<T> return type.
// To avoid processing unexpected or malicious queries, use the validation settings on QueryableAttribute to validate incoming queries.
// For more information, visit http://go.microsoft.com/fwlink/?LinkId=279712.
//config.EnableQuerySupport();
// To disable tracing in your application, please comment out or remove the following line of code
// For more information, refer to: http://www.asp.net/web-api
config.EnableSystemDiagnosticsTracing();
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("text/html"));
}
}
}
in MVC Project i have written following code in script tag(on load form) to refer WEB API Service,
$(document).ready(function () {
jQuery.support.cors = true;
$.ajax({
url: 'http://localhost:18715/api/student',
type: 'GET',
dataType: 'json',
success: function (data) {
alert('success');
},
error: function (x) {
alert(x.status);
}
});
});
If i add reference of Web API project to MVC project then it's working fine but one of my friend told services should not be referred like that, Please guide me how to refer/include the hosted/cross domain running web api project to my MVC Project?
What you have done is not bad(at least - it is not forbidden ;)) but by referencing WebAPI directly in a MVC project you are binding it to the one, specific application, what will prevent you from reusing API in other projects/services.
In my opinion, WebAPI project should be hosted as another application(it is up to you whether it should be a self-hosted OWIN application/webservice/simple API application), what gives you some benefits:
it is separated from your MVC application logic
it can be deployed separately
it can be used by other applications/services
it is easier to maintain
Think of WebAPI as a RESTful webservice, an API which can be used by your applications or third-party applications.
To be honest using WebAPI directly in MVC just to feed your views some data seems like a little waste. What you are doing can be done thanks to JsonResult actions in your MVC controller. It is not ideal, but prevents you from creating another API project.

Categories