Web.config custom section not being recognized - web-config

I am trying to develop an application that uses the package SAML2.dll (which I downloaded with NuGet). To properly configure my application, we must add a few sections in the Web.config file:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
**<section name="saml2" type="SAML2.Config.Saml2Section, SAML2" />**
</configSections>
<connectionStrings>...</connectionStrings>
<appSettings>...</appSettings>
<system.web>...</system.web>
<system.webServer>
<modules>
<remove name="FormsAuthentication" />
</modules>
**<handlers>
<remove name="SAML2.Protocol.Saml20SignonHandler" />
<remove name="SAML2.Protocol.Saml20LogoutHandler" />
<remove name="SAML2.Protocol.Saml20MetadataHandler" />
<add name="SAML2.Protocol.Saml20SignonHandler" verb="*" path="Login.ashx" type="SAML2.Protocol.Saml20SignonHandler, SAML2" />
<add name="SAML2.Protocol.Saml20LogoutHandler" verb="*" path="Logout.ashx" type="SAML2.Protocol.Saml20LogoutHandler, SAML2" />
<add name="SAML2.Protocol.Saml20MetadataHandler" verb="*" path="Metadata.ashx" type="SAML2.Protocol.Saml20MetadataHandler, SAML2" />
</handlers>**
</system.webServer>
<runtime>...</runtime>
<entityFramework>...</entityFramework>
**<saml2>
<serviceProvider id="urn:issuer" server="http://localhost:3301/">
<endpoints>
<endpoint localpath="Login.ashx" type="signon" redirectUrl="~/AuthenticatedHomePage" />
<endpoint localpath="Logout.ashx" type="logout" redirectUrl="~/HomePage" />
<endpoint localpath="Metadata.ashx" type="metadata" />
</endpoints>
<nameIdFormats allowCreate="true">
<add format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" />
</nameIdFormats>
<authenticationContexts comparison="Exact">
<add context="urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport" referenceType="AuthnContextClassRef" />
</authenticationContexts>
</serviceProvider>
<identityProviders metadata="C:\Users\myUser\Desktop\testMetadata\metadata_Kit_net.xml" />
<metadata>
<contacts>
<contact type="Administrative" company="" givenName="" surName="" email="" phone="" />
</contacts>
<requestedAttributes>
<add name="urn:cn" />
</requestedAttributes>
</metadata>
</saml2>**
</configuration>
The issue is that the session tag has no recognized tags, I'm having 39 messages like (one for each element inside the tag):
impossible to find schema information for the element 'saml2'.
impossible to find schema information for the element 'serviceProvider'.
impossible to find schema information for the element 'id'.
...
I looked into my dll's source code (SAML2.dll) and it seams to have all the tags definitions (as written in the first Web.config part: ):
using System.Configuration;
namespace SAML2.Config
{
/// <summary>
/// SAML2 Configuration Section.
/// </summary>
public class Saml2Section : ConfigurationSection
{
/// <summary>
/// Gets the section name.
/// </summary>
public static string Name { get { return "saml2"; } }
#region Elements
/// <summary>
/// Gets or sets the actions to perform on successful processing.
/// </summary>
/// <value>The actions.</value>
[ConfigurationProperty("actions")]
public ActionCollection Actions
{
get { return (ActionCollection)base["actions"]; }
set { base["actions"] = value; }
}
/// <summary>
/// Gets or sets the identity providers.
/// </summary>
/// <value>The identity providers.</value>
[ConfigurationProperty("identityProviders")]
public IdentityProviderCollection IdentityProviders
{
get { return (IdentityProviderCollection)base["identityProviders"]; }
set { base["identityProviders"] = value; }
}
/// <summary>
/// Gets or sets the metadata.
/// </summary>
/// <value>The metadata.</value>
[ConfigurationProperty("metadata")]
public MetadataElement Metadata
{
get { return (MetadataElement)base["metadata"]; }
set { base["metadata"] = value; }
}
/// <summary>
/// Gets or sets the service provider.
/// </summary>
/// <value>The service provider.</value>
[ConfigurationProperty("serviceProvider")]
public ServiceProviderElement ServiceProvider
{
get { return (ServiceProviderElement)base["serviceProvider"]; }
set { base["serviceProvider"] = value; }
}
...
When I call the URL http://localhost:3301/Login.ashx, I'm having the error:
{"Attribute 'localpath' not recognized. (c:\users\myUser\documents\visual studio 2013\Projects\saml20app\saml20app\web.config line 98)"}, and it points exactly to the line
<endpoint localpath="Login.ashx" type="signon" redirectUrl="~/AuthenticatedHomePage" />
Can someone please help me with this error?
Thanks in advance for your help,
Marc

Got tried of trying to get this to work so I opened the assembly with ILSpy to see what it wanted:
<endpoint localPath="Login.ashx" type="SignOn" redirectUrl="~/AuthenticatedHomePage" />
<endpoint localPath="Logout.ashx" type="Logout" redirectUrl="~/HomePage" />
<endpoint localPath="Metadata.ashx" type="Metadata" />
The type attribute in the example web.config makes it unhappy too. Thankfully it lets you know the enumerated values it expects.
Hope this help.

Related

.NetCore code with sustainsys-saml2 does nothing

I have an .Net MVC project with SSO working. The SSO config looks like this:
<system.identityModel>
<identityConfiguration saveBootstrapContext="true">
<caches>
<sessionSecurityTokenCache type="Vixion.IdentityModel.Cache.SharedSessionSecurityTokenCache, Vixion.IdentityModel.Cache">
<cacheServiceAddress url="http://tvwapps35434d.kpnis.nl:1008/SessionSecurityTokenCacheService.svc" />
</sessionSecurityTokenCache>
</caches>
<audienceUris>
<add value="http://localhost:24442/" />
</audienceUris>
<securityTokenHandlers>
<remove type="System.IdentityModel.Services.Tokens.MachineKeySessionSecurityTokenHandler, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<add type="System.IdentityModel.Tokens.SessionSecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<add type="System.IdentityModel.Tokens.Saml2SecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</securityTokenHandlers>
<certificateValidation certificateValidationMode="None" />
<issuerNameRegistry type="System.IdentityModel.Tokens.ValidatingIssuerNameRegistry, System.IdentityModel.Tokens.ValidatingIssuerNameRegistry">
<authority name="http://vix-make-o:8080">
<keys>
<add thumbprint="5137c779a1e77a0f4a78abd356b0238912637469" />
</keys>
<validIssuers>
<add name="http://vix-make-o:8080" />
</validIssuers>
</authority>
</issuerNameRegistry>
</identityConfiguration>
</system.identityModel>
<system.identityModel.services>
<federationConfiguration>
<cookieHandler requireSsl="false" path="/" />
<wsFederation passiveRedirectEnabled="true" issuer="http://vix-make-o:8080" realm="http://localhost:24442/" requireHttps="false" reply="http://localhost:24442/" />
</federationConfiguration>
</system.identityModel.services>
According to the example here:
https://github.com/Sustainsys/Saml2/tree/master/Sustainsys.Saml2.AspNetCore2
I write this code in a new .NetCore app:
services.AddIdentity<IdentityUser, IdentityRole>()
.AddDefaultTokenProviders();
services.AddDistributedMemoryCache();
services.AddSession(options =>
{
options.Cookie.HttpOnly = true;
});
services.AddMvc()
.AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());
services.AddAuthentication()
.AddSaml2(options =>
{
options.SPOptions.EntityId = new EntityId("http://vix-make-o:8080");
options.IdentityProviders.Add(
new IdentityProvider(
new EntityId("http://vix-make-o:8080/ws_saml_metadata"), options.SPOptions)
{
//LoadMetadata = true
});
});
app.UseAuthentication();
app.UseSession();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
When I start the app, the browser goes straight to the index page. No error, no nothing. When I check with SAML Chrome Panel it shows no traffic at all.
I do not expect my code working, but it should at least do something to give me a hint to how to go further.
Any suggestions are welcome.
Thank you.
S.
Remove the web.config content. It is not used with the ASP.NET Core module.
Set back the LoadMetadata flag, or add the necessary config manually.
Set Saml2 as the default challenge protocol for authentication.
Finally, add an [Authorize] attribute to your controllers that should require authentication to initiate the authentication process.

UWP and FullTrustProcessLauncher missing in namaspeace

I am trying to launch powershell (some lightweight commands that all user can do) command from UWP application using FullTrustProcessLauncher.
Problem is I am getting that this name does not exists in current context.
My manifest is largly default so it looks like :
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
IgnorableNamespaces="uap mp">
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="PrototypeProject.App">
<Extensions>
<desktop:Extension Category="windows.fullTrustProcess" Executable="powershell.exe">
<desktop:FullTrustProcess>
<desktop:ParameterGroup GroupId="TestGroup" Parameters="ls"/>
</desktop:FullTrustProcess>
</desktop:Extension>
</Extensions>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
<rescap:Capability Name="runFullTrust"/>
</Capabilities>
</Package>
And class I am trying to call it from looks like:
using Windows.ApplicationModel;
using Windows.Foundation;
namespace FullTrustProcess
{
public class Ftp
{
public const string FtpParamGroupId = "TestGroup";
public void RunFtp()
{
IAsyncAction operation = FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync(FtpParamGroupId);
}
}
}
Now am I missing something??
It looks like I was missing - Windows Desktop Extensions for the UWP, in extensions reference

Cannot access identity claims in custom authorize attribute in MVC application

I am trying to do POC of switching from forms authentication in existing MVC 4 application to claims-based one, but cannot get custom authorize attribute working - have infinite redirect loop ending with known 'bad request' issue because of total cookie size...
And the reason - there is no authenticated identity (and correct Claims collection) in attribute context as I see it in debug despite I see successfully created identity with expected claims collection in SecurityTokenValidated handler.
So, it seems like it is somehow lost after OIDC middleware process it, and not unavailable in attribute context, therefore I cannot further check for 'role' claim.
Maybe I am missing something?
My OWIN Startup:
AntiForgeryConfig.UniqueClaimTypeIdentifier = "sub";
JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>();
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = CookieAuthenticationDefaults.AuthenticationType
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
AuthenticationType = "oidc",
//AuthenticationMode = AuthenticationMode.Active, // ? https://github.com/IdentityServer/IdentityServer3/issues/1963
Authority = OAuthServerUrl,
ClientId = "my_app",
RedirectUri = MyAppUrl,
ResponseType = "id_token token", //notice, if response type 'token' is requested, IdentityServer stops including the claims in the identity token, though we could set alwaysInclude=true for some scope claims (ex. for role)
Scope = "openid profile roles",
SignInAsAuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
PostLogoutRedirectUri = MyAppUrl,
Notifications = new OpenIdConnectAuthenticationNotifications
{
SecurityTokenValidated = n =>
{
var id = n.AuthenticationTicket.Identity;
//n.OwinContext.Authentication.SignIn(id);
//tried SignIn() explicitly, and even setting HttpContext.Current.User and Thread.CurrentPrincipal to n.AuthenticationTicket.Identity, but without luck
return Task.FromResult(0);
},
RedirectToIdentityProvider = async n =>
{
if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
{
var result =
await n.OwinContext.Authentication.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationType);
var idToken = result?.Identity.Claims.GetValue("id_token");
if (idToken != null)
{
n.ProtocolMessage.IdTokenHint = idToken;
}
}
await Task.FromResult(0);
}
}
});
My custom attribute inherited from System.Web.Mvc.AuthorizeAttribute:
public class ClaimsAuthorizeAttribute : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
//var owinContext = HttpContext.Current.GetOwinContext();
if (filterContext.HttpContext.User.Identity.IsAuthenticated)
{
// 403 we know who you are, but you haven't been granted access
filterContext.Result = new HttpStatusCodeResult(System.Net.HttpStatusCode.Forbidden);
}
else
{
// 401 who are you? go login and then try again
filterContext.Result = new HttpUnauthorizedResult();
}
}
}
where filterContext.HttpContext.User.Identity (also tried HttpContext.Current.User and Thread.CurrentPrincipal) has Claims collection with single 'name' claim from LOCAL AUTHORITY issuer (default one?).
I also modified Web.config to disable forms auth:
<authentication mode="None">
...
<membership>
<providers>
<clear />
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="999" minRequiredPasswordLength="7" minRequiredNonalphanumericCharacters="1" passwordAttemptWindow="3" passwordStrengthRegularExpression="" applicationName="Audit" />
<!--<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="999" minRequiredPasswordLength="7" minRequiredNonalphanumericCharacters="1" passwordAttemptWindow="3" passwordStrengthRegularExpression="" applicationName="Audit" />-->
</providers>
</membership>
<profile>
<providers>
<clear />
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ApplicationServices" applicationName="Audit" />
<!--<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ApplicationServices" applicationName="Audit" />-->
</providers>
</profile>
<roleManager enabled="true">
<roleManager enabled="false">
<providers>
<clear />
<add connectionStringName="ApplicationServices" applicationName="Audit" name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<add applicationName="Audit" name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<!--<add connectionStringName="ApplicationServices" applicationName="Audit" name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />-->
<!--<add applicationName="MyApp" name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />-->
</providers>
</roleManager>
...
<handlers>
<remove name="FormsAuthentication" />
<remove name="RoleManager" />
UPDATE 1: I've migrated app from MVC 4 to the latest MVC 5 hoping it is MVC 4 related issue, but, unfortunately, no difference. Apparently, something wrong with my client application/configuration.

ASP.NET Routing in rest service not working in IIS

I created a simple rest service with routing enabled. The routing is properly working when i run it locally i.e using asp.net development server. But when I deploy the application in IIS (IIS 7.5) then it and try to access the method in the service i get the error HTTP 404.0 Not found. Here is my code :
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class HelloWorldService
{
[WebGet(UriTemplate = "Date")]
public DateTime Date()
{
return System.DateTime.Now;
}
}
Global.asax:
protected void Application_Start(object sender, EventArgs e)
{
RegisterRoutes();
}
private void RegisterRoutes()
{
RouteTable.Routes.Add(new ServiceRoute("ServiceData", new WebServiceHostFactory(), typeof(HelloWorldService)));
}
Web.config:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</modules>
</system.webServer>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"/>
</webHttpEndpoint>
</standardEndpoints>
</system.serviceModel>
</configuration>
I also Enabled HTTP Redirection Feature under
Windows Features -> Internet Information Services -> Word Wide Web services -> Common HTTP Features
I also tried Adding handlers like
<handlers>
<add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler, System.Web,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
</handlers>
Also i have tried all the other solutions that were suggested on the web but nothing works. Thanks in advance for any help.
Something is wrong with your RegisterRoutes(). It should be:
private void RegisterRoutes()
{
// Edit the base address of Service1 by replacing the "Service1" string below
RouteTable.Routes.Add(new ServiceRoute("HelloWorldService", new WebServiceHostFactory(), typeof(HelloWorldService)));
}

Delete not Working in WCF rest service throwing (405) Method Not Allowed

I have created WCF RESTful service which uses simple database behind it and just trying to working on put, get,post and delete items. Right now post ,put and get is working. But the delete is n't working. Some forums telling that I need to disable the WebDAV module. I did that and then I got PUT to work. But I can not get DELETE to work. Whenever I call DELETE verb through my service I got the following error:
The remote server returned an unexpected response: (405) Method Not Allowed.
Can any one help me on this?
I have not yet found one comprehensive answer for PUT and DELETE being overridden and returning 405s for restful WCF services anywhere else, so I'm going to post it here.
This problem can be addressed easily by simply uninstalling WebDAV from the machine via either the role manager (on a server) or through Add/Remove windows features. If that is an acecceptible approach, you can stop reading now.
The commonly recommended fix here is to simply remove the WebDAV module from your site, appending something like the following to your web.config:
<system.webServer>
<modules>
<remove name="WebDAVModule" />
</modules>
</system.webServer>
The problem here is that now your WCF app has no way of knowing how to handle PUT and DELETE at all. So to solve this, some solutions suggest making the follwing modification:
<modules runAllManagedModulesForAllRequests="true">
<system.webServer>
<modules>
<remove name="WebDAVModule" />
</modules>
</system.webServer>
This may be satisfactory for most, but I did not like the idea of having our service uselessly loading everything up for every call when it wasn't necessary. So I refined the approach a bit by manually mapping the extensionless URL handler to all HTTP verbs (probably could be refined to just the necessary ones)
<system.webServer>
<modules>
<remove name="WebDAVModule" />
</modules>
<handlers>
<remove name="WebDAV" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
I only tested this on R2 64 and 7 64, so ymmv. But hopefully this helps.
There seems to have some similar questions on StackOverflow already:
WCF Service 405 Method Not Allowed Exception
WCF The request failed with HTTP status 405: Method Not Allowed
WCF Service Returning "Method Not Allowed"
Hope one of them helps.
I've used the WebChannelFactory approach in the client side to consume the REST service. I've created the Service Reference using the normal "Add Service Reference" approach. This doesn't add [WebGet(UriTemplate = "/")].
After I added these for all Operation on Client side proxy class just like the Service Contract, it started working.
Adding Codes to the Web.config File
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<system.serviceModel>
<behaviors >
<serviceBehaviors>
<behavior name="http">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="www">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<services>
<service behaviorConfiguration="http" name="REST.CRUD.Alternativ">
<endpoint address=""
binding="webHttpBinding"
behaviorConfiguration="www"
contract="REST.CRUD.IAlternativ"
bindingConfiguration="rest">
</endpoint>
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange">
</endpoint>
</service>
</services>
<bindings>
<webHttpBinding>
<binding allowCookies="true" name="rest">
<security mode="None"></security>
</binding>
</webHttpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<directoryBrowse enabled="true" />
<security>
<requestFiltering>
<verbs>
<add verb="GET" allowed="true" />
<add verb="POST" allowed="true" />
<add verb="DELETE" allowed="true" />
<add verb="PUT" allowed="true" />
</verbs>
</requestFiltering>
</security>
</system.webServer>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="v11.0" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
<connectionStrings>
<add name="KendoDB" connectionString="Data Source=(localDB)\v11.0;Initial Catalog=Kendo;Integrated Security=True;Pooling=False" providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
PersonDTO
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
namespace REST.CRUD
{
public class PersonDTO
{
public int ID { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
}
public class KendoContext : DbContext
{
public KendoContext():base("KendoDB"){}
public DbSet<PersonDTO> PersonDTOs { get; set; }
}
}
IAlternativ.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Web.Services;
namespace REST.CRUD
{
[ServiceContract]
public interface IAlternativ
{
[WebInvoke(Method = "POST",
BodyStyle = WebMessageBodyStyle.WrappedRequest,
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
List<PersonDTO> GetAll();
[WebInvoke(Method = "GET",
BodyStyle = WebMessageBodyStyle.WrappedRequest,
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
PersonDTO Get(int ID, string f, string l);
[WebInvoke(Method = "DELETE",
BodyStyle = WebMessageBodyStyle.WrappedRequest,
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
String Delete(int ID, string f, string l);
[WebInvoke(Method = "PUT",
BodyStyle = WebMessageBodyStyle.WrappedRequest,
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
String Update(int ID, string f, string l);
}
}
Alternativ.svc.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Web.Script.Services;
using System.Web.Services;
namespace REST.CRUD
{
public class Alternativ : IAlternativ
{
public List<PersonDTO> GetAll()
{
var db = new KendoContext();
return db.PersonDTOs.Select(c => c).ToList();
}
public PersonDTO Get(int ID, string f, string l)
{
var db = new KendoContext();
return db.PersonDTOs.Where(c => c.ID == ID).Select(c => c).First();
}
public String Delete(int ID, string f, string l)
{
//Delete Code
return "OK";
}
public String Update(int ID, string f, string l)
{
//Update Code
return "OK";
}
}
}
[Build and Run the WCF Project(F5)].
Add jquery to DOM for test(Paste to Console)
(function() {
if (! window.jQuery ) {
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.src = '//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js';
(document.getElementsByTagName('head')[0] ||
document.getElementsByTagName('body')[0]).appendChild(s);
}
}());
Add functions to Console
function POST(){
$.ajax({
type: "POST", //GET,POST,PUT or DELETE verb
url: "/Alternativ.svc/GetAll", // Location of the service
data: '{"ID":"1"}', //Data to be sent to server
dataType: "json", // content type sent to server
contentType: "application/json; charset=utf-8", //Expected data format from server
processdata: false, //True or False
success: function (response) {
console.log(response);
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.statusText);
}
});
}
function GET(){
$.ajax({
type: "GET", //GET,POST,PUT or DELETE verb
url: "/Alternativ.svc/Get", // Location of the service
data: {ID:1}, //Data to be sent to server
dataType: "json", // content type sent to server
contentType: "application/json; charset=utf-8", //Expected data format from server
processdata: true, //True or False
success: function (response) {
console.log(response);
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.statusText);
}
});
}
function DELETE(){
$.ajax({
type: "DELETE", //GET,POST,PUT or DELETE verb
url: "/Alternativ.svc/Delete", // Location of the service
data: '{"ID":"1"}', //Data to be sent to server
dataType: "json", // content type sent to server
contentType: "application/json; charset=utf-8", //Expected data format from server
processdata: false, //True or False
success: function (response) {
console.log(response);
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.statusText);
}
});
}
function PUT(){
$.ajax({
type: "PUT", //GET,POST,PUT or DELETE verb
url: "/Alternativ.svc/Update", // Location of the service
data: '{"ID":"1"}', //Data to be sent to server
dataType: "json", // content type sent to server
contentType: "application/json; charset=utf-8", //Expected data format from server
processdata: false, //True or False
success: function (response) {
console.log(response);
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.statusText);
}
});
}
Call functions
DELETE();
PUT();
GET();
POST();