WCF restful service access denied when trying to upload file? - asp.net

I made a WCF restful service for uploading the files to specific directory on the server, and a small ASP.NET web application that can upload the files threw this web service. The problem is that I am constantly getting the error of access denied. I tried to give all the privileges to a folder for testing purposes (Full control for Everyone, Full control for IIS_IUSRS, AppPool of WCF and Web service, etc.), but still the same error shows. Below is the code of Service and Web application:
Main WCF service class
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple,
InstanceContextMode = InstanceContextMode.PerCall,
IgnoreExtensionDataObject = true,
IncludeExceptionDetailInFaults = true)]
public class UploadFile : IUploadFile
{
public ReturnValue ExcelUpload(Stream File)
{
using (FileStream writer = new FileStream(#"C:\Users\Public\Documents", FileMode.Create))
{
int ReadCount = 0;
var buffer = new byte[8192];
while ((ReadCount = File.Read(buffer, 0, buffer.Length)) != 0)
{
writer.Write(buffer, 0, ReadCount);
}
}
return new ReturnValue() { IsSuccessfull = true };
}
public ReturnValue test(int id)
{
return new ReturnValue() { IsSuccessfull = true };
}
}
WCF service contract
[ServiceContract(Name = "ExcelUpload.IUploadFile")]
public interface IUploadFile
{
[OperationContract]
[DataContractFormat]
[WebInvoke(Method = "*",
UriTemplate = "UploadExcel/",
BodyStyle = WebMessageBodyStyle.Bare,
ResponseFormat = WebMessageFormat.Json)]
ReturnValue ExcelUpload(Stream File);
// TODO: Add your service operations here
[OperationContract]
[DataContractFormat]
[WebInvoke(Method = "POST",
UriTemplate = "test/",
BodyStyle = WebMessageBodyStyle.Bare,
ResponseFormat = WebMessageFormat.Json)]
ReturnValue test(int id);
}
// Use a data contract as illustrated in the sample below to add composite types to service operations.
[DataContract]
public class ReturnValue
{
[DataMember]
public bool IsSuccessfull { get; set; }
}
WCF service web.config
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
<serviceActivations>
<add relativeAddress="~/UploadFile.svc" service="ExcelUpload.UploadFile"/>
</serviceActivations>
</serviceHostingEnvironment>
<bindings>
<webHttpBinding>
<binding name="crossDomain"
maxBufferSize="2147483647"
maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647"
transferMode="Streamed"
sendTimeout="00:05:00"
crossDomainScriptAccessEnabled="true">
<readerQuotas maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647"/>
<security mode="None" />
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="defaultServiceBehaviour">
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceThrottling maxConcurrentCalls="100" maxConcurrentInstances="100" maxConcurrentSessions="100"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="defaultEndpointBehaviour">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="ExcelUpload.UploadFile" behaviorConfiguration="defaultServiceBehaviour">
<endpoint address="" behaviorConfiguration="defaultEndpointBehaviour" bindingConfiguration="crossDomain" binding="webHttpBinding" contract="ExcelUpload.IUploadFile"></endpoint>
</service>
</services>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
<add binding="basicHttpBinding" scheme="http"/>
</protocolMapping>
</system.serviceModel>
<system.webServer>
<security>
<authentication>
<anonymousAuthentication enabled="true"/>
</authentication>
<requestFiltering allowHighBitCharacters="true">
<verbs allowUnlisted="false">
<add verb="POST" allowed="true"/>
<add verb="GET" allowed="true"/>
</verbs>
</requestFiltering>
</security>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
Web application
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="UploadTest.WebForm1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Uploading using WCF REST API</title>
<script type="text/javascript">
function uploadBlobOrFile(blobOrFile) {
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://intranet-services.tosama.si/CroSalesExcelUpload/UploadFile.svc/UploadExcel/', true);
xhr.setRequestHeader('Content-length', blobOrFile.size);
xhr.onload = function (e) {
progressBar.value = 0;
progressBar.textContent = progressBar.value;
};
// Listen to the upload progress.
var progressBar = document.querySelector('progress');
xhr.upload.onprogress = function (e) {
if (e.lengthComputable) {
progressBar.value = (e.loaded / e.total) * 100;
progressBar.textContent = progressBar.value; // Fallback.
}
};
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
};
xhr.send(blobOrFile);
}
</script>
</head>
<body>
<input id="filePicker" type="file" name="Package" accept="image/*"/>
<br />
<progress min="0" max="100" value="0">0% complete</progress>
<br />
<button title="upload"
onclick="if (filePicker.files[0]) uploadBlobOrFile(filePicker.files[0])">
<span>Upload</span>
</button>
</body>
</html>

Very basic thing is, why are you trying to create object for directory?
#"C:\Users\Public\Documents"
try changing to #"C:\Users\Public\Documents\MyFile.txt"
Here you can use any type of file instead of txt.
And don't forget to set limits for your file to be uploaded.
Hope it helps.. !

Related

Asp.net core 2.0 website, cache-control not working as expected

In my asp.net core 2.0 application, I am trying to add expiration header (cache-control) into response header for all static resources but it's not adding it all.
Below is my code
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddMvc().AddJsonOptions(jsonOptions =>
{
jsonOptions.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
// handle loops correctly
jsonOptions.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
// services.AddResponseCaching();
services.AddSingleton<Microsoft.Extensions.Configuration.IConfiguration>(Configuration);
services.AddSingleton<Microsoft.Extensions.Configuration.IConfiguration>(Configuration);
services.AddSingleton<IMapper>(sp => AutoMapperConfiguration.CreateMapper());
var builder = new ContainerBuilder();
builder.Populate(services);
ApiFactory.RegisterDependencies(builder);
this.ApplicationContainer = builder.Build();
return new AutofacServiceProvider(this.ApplicationContainer);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
var options = new RewriteOptions()
.AddRedirect("rent/(.*)", "/$1")
.AddRedirect("explore/(.*)", "/$1");
app.UseRewriter(options);
app.UseMyMiddleware();
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc(routes =>
{
routes
.MapRoute(
name: "goto_sitemap",
template: "sitemap.xml",
defaults: new { controller = "Home", action = "Sitemap" });
routes.MapRoute(name: "default", template: "{controller=Home}/{action=Index}/{id?}");
});
}
Edit: I removed custom header and added into middleware
public static class BuilderExtensions
{
public static IApplicationBuilder UseMyMiddleware(this IApplicationBuilder app)
{
return app.UseMiddleware<MyMiddleware>();
}
}
public class MyMiddleware
{
RequestDelegate _next;
public MyMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
if (context.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
{
await _next(context);
}
else
{
Regex rx = new Regex(#"\b(?:https?:\/\/)?[^\/:]+\/.*?\/explore|\/rent|\/about|\/blog|\/partners|\/partner|\/property|\/partnerListing|\/areaguide|\/rentalinquiry|\/termcondition|\/sitemap|\/privacypolicy|\/advertise|\/expired|\/contactus|favicon|\/images|\/api|\/fonts|\/templates|\/css|\/lib|\/js|\/sitemap.xml|\/ror.xml|\/sitemap_mobile.xml",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
if (context.Request.Path.Value == "/")
{
await _next(context);
}
else if (rx.IsMatch(context.Request.Path.Value))
{
await _next(context);
if (context.Request.Path.Value.EndsWith(".css") || context.Request.Path.Value.EndsWith(".js")
|| context.Request.Path.Value.EndsWith(".jpg") || context.Request.Path.Value.EndsWith(".jpeg")
|| context.Request.Path.Value.EndsWith(".gif") || context.Request.Path.Value.EndsWith(".png"))
{
//Set css and js files to be cached for 7 days
TimeSpan maxAge = new TimeSpan(7, 0, 0, 0); //7 days
context.Response.Headers.Append("Cache-Control", "public,max-age=" + maxAge.TotalSeconds.ToString("0"));
}
}
else
{
string path = "/explore" + context.Request.Path.Value;
context.Request.Path = new PathString(path);
await _next(context);
}
}
}
}
It was not working, so I added the same in web.config file also, which is also not working.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<staticContent>
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="2.00:00:00" cacheControlCustom="public" />
</staticContent>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\xxxx.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout">
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" />
</environmentVariables>
</aspNetCore>
<httpCompression>
<dynamicTypes>
<remove mimeType="text/event-stream" />
<remove mimeType="*/*" />
<add mimeType="*/*" enabled="true" />
<add mimeType="text/event-stream" enabled="true" />
<add mimeType="image/jpeg" enabled="false" />
<add mimeType="font/woff2" enabled="false" />
<add mimeType="image/png" enabled="false" />
<add mimeType="image/gif" enabled="false" />
</dynamicTypes>
<staticTypes>
<remove mimeType="image/svg+xml" />
<add mimeType="image/jpeg" enabled="false" />
<add mimeType="image/svg+xml" enabled="false" />
<add mimeType="font/woff2" enabled="false" />
<add mimeType="image/png" enabled="false" />
<add mimeType="image/gif" enabled="false" />
</staticTypes>
</httpCompression>
</system.webServer>
</configuration>
it stopped working 2nd time onwards (checking with hard refresh)

Compress filter at the action level for ASP.NET Core MVC

I'm migrating an ASP.NET MVC 5 application to ASP.NET Core 2.1. In the "old" application I had a Compress filter that was apply Gzip to the response of specific requests. That way I was able to compress only specific requests and not all the requests.
Based on what I understand, ASP.NET Core has a different approach using middlewares and it only gives you the chance to apply compression to all the requests (adding it to the pipeline) or not applying it at all.
Is there a way to achieve what I want by creating an ActionFilterAttribute? this was my old code:
public class CompressAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var acceptEncoding = filterContext.HttpContext.Request.Headers["Accept-Encoding"];
if (string.IsNullOrEmpty(acceptEncoding))
return;
acceptEncoding = acceptEncoding.ToLower();
var response = filterContext.HttpContext.Response;
if (acceptEncoding.Contains("gzip"))
{
response.AppendHeader("Content-Encoding", "gzip");
response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
}
else if (acceptEncoding.Contains("deflate"))
{
response.AppendHeader("Content-Encoding", "deflate");
response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
}
}
}
I also had task for compressing responses only for some specific actions/controllers
Finally I've found a solution based on ActionFilterAttribute. here is an example
namespace CommonWebApi.MiddleWare
{
/// <summary>
/// Attribute for enabling Brotli/GZip/Deflate compression for specied action
/// </summary>
public class ResponseCompressionAttribute : ActionFilterAttribute
{
private Stream _originStream = null;
private MemoryStream _ms = null;
public override void OnActionExecuting(ActionExecutingContext context)
{
HttpRequest request = context.HttpContext.Request;
string acceptEncoding = request.Headers["Accept-Encoding"];
if (string.IsNullOrEmpty(acceptEncoding)) return;
acceptEncoding = acceptEncoding.ToUpperInvariant();
HttpResponse response = context.HttpContext.Response;
if (acceptEncoding.Contains("BR", StringComparison.OrdinalIgnoreCase))//Brotli
{
if (!(response.Body is BrotliStream))// avoid twice compression.
{
_originStream = response.Body;
_ms = new MemoryStream();
response.Headers.Add("Content-encoding", "br");
response.Body = new BrotliStream(_ms, CompressionLevel.Optimal);
}
}
else if (acceptEncoding.Contains("GZIP", StringComparison.OrdinalIgnoreCase))
{
if (!(response.Body is GZipStream))
{
_originStream = response.Body;
_ms = new MemoryStream();
response.Headers.Add("Content-Encoding", "gzip");
response.Body = new GZipStream(_ms, CompressionLevel.Optimal);
}
}
else if (acceptEncoding.Contains("DEFLATE", StringComparison.OrdinalIgnoreCase))
{
if (!(response.Body is DeflateStream))
{
_originStream = response.Body;
_ms = new MemoryStream();
response.Headers.Add("Content-encoding", "deflate");
response.Body = new DeflateStream(_ms, CompressionLevel.Optimal);
}
}
base.OnActionExecuting(context);
}
public override async void OnResultExecuted(ResultExecutedContext context)
{
if ((_originStream != null) && (_ms != null))
{
HttpResponse response = context.HttpContext.Response;
await response.Body.FlushAsync();
_ms.Seek(0, SeekOrigin.Begin);
response.Headers.ContentLength = _ms.Length;
await _ms.CopyToAsync(_originStream);
response.Body.Dispose();
_ms.Dispose();
response.Body = _originStream;
}
base.OnResultExecuted(context);
}
}
}
known limitations/essentials:
MemoryStream is required only to get length of compressed stream. This value should be set to response.Headers.ContentLength for correct work.
currently it works only for 3 types of compression.
I found two different approaches to apply compression to specific scenarios:
1) Create a middleware and analyze the request before applying compression. I did not like this approach because the middleware would run for all the requests and would have to examine the request information, affecting the performance.
2) Modify the Web.config file (this is the approach I took) and apply compression to certain dynamic and static types. When an ASP.NET Core app is published, a web.config is automatically generated. We can edit the web.config file and add compression like I did in the following example:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<urlCompression doStaticCompression="true" doDynamicCompression="true" />
<httpCompression>
<dynamicTypes>
<clear />
<add enabled="true" mimeType="text/*" />
<add enabled="true" mimeType="message/*" />
<add enabled="true" mimeType="application/x-javascript" />
<add enabled="true" mimeType="application/javascript" />
<add enabled="true" mimeType="application/json" />
<add enabled="false" mimeType="*/*" />
<add enabled="true" mimeType="application/atom+xml" />
<add enabled="true" mimeType="application/atom+xml;charset=utf-8" />
</dynamicTypes>
<staticTypes>
<clear />
<add enabled="true" mimeType="text/*" />
<add enabled="true" mimeType="message/*" />
<add enabled="true" mimeType="application/javascript" />
<add enabled="true" mimeType="application/atom+xml" />
<add enabled="true" mimeType="application/xaml+xml" />
<add enabled="false" mimeType="*/*" />
</staticTypes>
</httpCompression>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\YourApplicationName.dll" stdoutLogEnabled="false" stdoutLogFile="\\?\%home%\LogFiles\stdout" />
</system.webServer>
</configuration>

show original json data using wcf service method

I am using wcf service where i have to access wcf service method and show the returned json data in the browser itself.
Currently i tried string method so json data is showing as json string format which is incorrect.
I have gone through this link and tried with my code but not getting any
data because of complete data is in one list.
Below is the interface IService code:
[ServiceContract]
public interface IService1
{
[OperationContract]
List<SuccessStoryApp> GetSuccessStoryJson();
[OperationContract]
[WebInvoke(Method = "GET",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/GetBlogList/")]
string GetBlogList();
}
Service1.svc Code:
public string GetBlogList()
{
log.Info("GetBlostList method entered");
List<SuccessStoryApp> storyList = new List<SuccessStoryApp>();
string jsonString = string.Empty;
var jsonData = GetSuccessStoryJson();
storyList = jsonData.Select(x => new SuccessStoryApp
{
Author = x.Author,
AuthorSlug = x.AuthorSlug,
Available = x.Available,
Category = x.Category,
CountryCode = x.CountryCode,
Description = x.Description,
LanguageCode = x.LanguageCode,
PublishedDate = x.PublishedDate,
Quote = x.Quote,
ShortDescription = x.ShortDescription,
StoryImageAlt = x.StoryImageAlt,
StoryImageTitle = x.StoryImageTitle,
StoryImageURL = x.StoryImageURL,
Tags = x.Tags,
Text = x.Tags,
Title = x.Title,
TitleImageURL = x.TitleImageURL,
Type = x.Type
}).ToList();
if (storyList.Count > 0)
{
var json = JsonConvert.SerializeObject(storyList);
jsonString = json;
}
else
{
jsonString = "Some error occurred";
}
return jsonString;
}
and below is my web.config service configuration:
<system.serviceModel>
<services>
<service behaviorConfiguration="Default" name="BlogService.Service1">
<endpoint address="" behaviorConfiguration="webBehavior" binding="webHttpBinding" contract="BlogService.IService1" bindingConfiguration="WHB" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:60500/Service1.svc" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="webBehavior">
<webHttp defaultOutgoingResponseFormat="Json" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
<behavior name="Default">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="WHB" crossDomainScriptAccessEnabled="true">
<security mode="None" />
</binding>
</webHttpBinding>
</bindings>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
I am able to debug GetBlogList method and it is returning currently json string.
I wanted to return here original json format.

WCF service call fails while Calling WCF service using JQuery

I am using asp.net. I have created an WCF service in C# and hosted on IIS server. I am calling this service using JQuery in my asp.net web application. When I called the service using JQuery, it is going to error function and in alert there is empty message.
Calling service form .aspx page.
<script src="Script/jquery-1.10.2.min.js" type="text/javascript"></script>
<script type="text/javascript" language="javascript">
function callService()
{
var value = 10;
$.ajax({
type: "POST",
url: "http://localhost/IISWCF/Service1.svc/getdata",
contentType: "application/json; charset=utf-8",
data: '{"value": "' + value + '"}',
dataType: "json",
processdata: true, //True or False
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("error: " + errorThrown);
},
success: function(msg) {
alert(msg.d);
}
});
}
</script>
<script type="text/javascript" language="javascript">
$(document).ready(function(){
callService();
})
</script>
Service1.svc file
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
}
IService1.cs file
namespace WcfService1
{
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json)]
string GetData(int value);
}
}
WCF Web.config file
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="WcfService1.Service1Behavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="EndpBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="WcfService1.Service1" behaviorConfiguration="WcfService1.Service1Behavior">
<endpoint behaviorConfiguration="EndpBehavior" address="" binding="webHttpBinding" contract="WcfService1.IService1">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
Please help me to resolved this issue.
I have added some dummy code, probably few methods are not used also. But you can test your code with the dummy DoubleUp method. Also, you have defined endpointbehavior, but is it used, it should be applied to endpoint and its important. Ref my example below.
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
[ServiceContract]
public interface ICalculatorService
{
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/DoubleUp/{val}")]
int DoubleUp(string val);
[OperationContract]
[WebGet(ResponseFormat=WebMessageFormat.Json, UriTemplate="/{value}/{value1}")]
int AddValues(string value, string value1);
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json)]
string ConcatenateString(string stringArray);
}
public class CalculationService : ICalculatorService
{
public int DoubleUp(string val)
{
return 2 * Convert.ToInt32(val);
}
public int AddValues(string value, string value1)
{
return Convert.ToInt32(value) + Convert.ToInt32(value1);
}
public string ConcatenateString(string stringArray)
{
string returnString = string.Empty;
returnString += stringArray;
return returnString;
}
}
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="JSONBinding"></binding>
</webHttpBinding>
<basicHttpBinding>
<binding name="basicHTTP">
<security mode="None">
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="basicBehavior">
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="JSON">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="RestWCFService.CalculationService" behaviorConfiguration="basicBehavior">
<endpoint address="basic" binding="basicHttpBinding" contract="RestWCFService.ICalculatorService" bindingName ="basicHTTP"></endpoint>
<endpoint behaviorConfiguration="JSON" binding="webHttpBinding" bindingConfiguration="JSONBinding" contract="RestWCFService.ICalculatorService" name="JSONService"></endpoint>
</service>
</services>
<protocolMapping>
<add binding="basicHttpBinding" scheme="http"/>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
/* This is the code for accessing the service via REST call
WebClient client = new WebClient();
string s = client.DownloadString("http://localhost/RestWCFService/CalculationService.svc/DoubleUp/3");
Console.WriteLine("Response returned is:" + s);
*/
/*This is the section to access service via Proxy */
ChannelFactory<RestWCFService.ICalculatorService> client = new ChannelFactory<RestWCFService.ICalculatorService>();
client.Endpoint.Address = new EndpointAddress("http://localhost/RestWCFService/CalculationService.svc/basic");
client.Endpoint.Binding = new BasicHttpBinding();
RestWCFService.ICalculatorService service = client.CreateChannel();
int val = service.DoubleUp("2");
((IClientChannel)service).Close();
client.Close();
Console.WriteLine("Values returned is:" + val.ToString());
/*Programmatic access ends here */
Console.ReadLine();
Your service is working fine. Made some changes.
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, UriTemplate="/GetData?value={value}")]
string GetData(int value);
}
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
}
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="WcfService1.Service1Behavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="EndpBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="WcfService1.Service1" behaviorConfiguration="WcfService1.Service1Behavior">
<endpoint behaviorConfiguration="EndpBehavior" address="" binding="webHttpBinding" contract="WcfService1.IService1">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Access the service on browser and you get the result.
http://localhost/IISWCF/Service1.svc/GetData?value=1
If your service is working fine, then try this JS as your JS is incorrect for this service request.
<script type="text/javascript" language="javascript">
function callService() {
var value = 10;
$.ajax({
type: "GET",
url: "http://localhost/IISWCF/Service1.svc/GetData?value=1",
contentType: "application/json; charset=utf-8",
data: '{"value": "' + value + '"}',
dataType: "text",
processdata: false, //True or False
statusCode: {
404: function () {
alert("page not found");
},
200: function () {
alert('HTTP HIT WAS Good.');
},
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("error: " + errorThrown);
},
success: function (msg) {
alert(msg);
}
});
}

Failed to add a service. Service metadata may not be accessible. Make sure your service is running and exposing metadata

I am writing WCF Service. My code is
namespace RestService
{
public class user
{
public user(string i, string b, string l)
{
id = i;
badgeNumber = b;
login = l;
}
public string id { get; set; }
public string badgeNumber { get; set; }
public string login { get; set; }
}
public class RestServiceImpl : IRestServiceImpl
{
#region IRestServiceImpl Members
public string XMLData(string id)
{
return "You requested product " + id;
}
public user[] JSONData(string id)
{
OleDbConnection connection = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\confiz\Desktop\att2000.mdb");
connection.Open();
OleDbCommand command = new OleDbCommand("SELECT count(*) FROM USERINFO", connection);
int users_count = (int)command.ExecuteScalar();
command = new OleDbCommand("SELECT * FROM USERINFO", connection);
OleDbDataReader reader = command.ExecuteReader();
// string jsonString = "";
user[] users = new user[users_count];
int i=0;
while (reader.Read())
{
users[i].id = reader["USERID"].ToString();
users[i].badgeNumber = reader["Badgenumber"].ToString();
users[i].login = reader["SSN"].ToString();
/* user = new user(reader["USERID"].ToString(), reader["Badgenumber"].ToString(), reader["SSN"].ToString());
System.Web.Script.Serialization.JavaScriptSerializer jsSerializer;
jsSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
System.Text.StringBuilder sbUser = new System.Text.StringBuilder();
jsSerializer.Serialize(user, sbUser);
string json = sbUser.ToString();
*/
// jsonString = jsonString + json;
i++;
}
connection.Close();
return users;
}
#endregion
}
}
My Web.config file is like this
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="RestService.RestServiceImpl" behaviorConfiguration="ServiceBehaviour">
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<endpoint address ="" binding="webHttpBinding" contract="RestService.IRestServiceImpl" behaviorConfiguration="web">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehaviour">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
but when i run this code i get error
Failed to add a service. Service metadata may not be accessible. Make sure your service is running and exposing metadata.
Error Details: Error: Cannot obtain Metadata from RestServiceImpl.svc If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address.
I'm going to say it's because you don't have an address for your endpoint in the web.config.
<endpoint address ="" binding="webHttpBinding"
contract="RestService.IRestServiceImpl" behaviorConfiguration="web">

Resources