show original json data using wcf service method - asp.net

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.

Related

WCF restful service access denied when trying to upload file?

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.. !

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);
}
});
}

WCF : Service call failed: 400Bad Request

I am using asp.net 3.5. I have developed the WCF Service. I try to call the WCF Service form JQUERY, But I am getting the error as
Service call failed: 400 Bad Request
MY Code is as follows:-
IService:-
[ServiceContract]
public interface IService
{
[OperationContract]
//[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json)]
[WebInvoke(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, Method = "GET", BodyStyle = WebMessageBodyStyle.WrappedRequest)]
CommandStatus getCommandStatus(string Id, string UnitNumber, string UnitType);
}
Service :-
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class Service : IService
{
public CommandStatus getCommandStatus(string Id, string UnitNumber, string UnitType)
{
CommandStatus objCommandStatus = new CommandStatus();
CommandsBLL objCommandsBLL = new CommandsBLL();
DataSet ds = new DataSet();
ds = objCommandsBLL.getCommandStatus(Convert.ToInt32(Id), UnitNumber, Convert.ToInt32(UnitType));
if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
{
objCommandStatus.ID = Convert.ToString(ds.Tables[0].Rows[0]["IOMH_ID"]);
objCommandStatus.UnitType = Convert.ToString(ds.Tables[0].Rows[0]["IOMH_UnitType"]);
}
return objCommandStatus;
}
}
Web.Config file is
<system.serviceModel>
<services>
<service behaviorConfiguration="ServiceBehavior" name="Service">
<endpoint address="" binding="wsHttpBinding" contract="IService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="AjaxBehavior">
<enableWebScript />
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
and Final my Jquery call is
var ID = 10;
var UnitNumber = '10001';
var UnitType = 1;
function CallService() {
var input =
{
ID: "10",
UnitNumber: "10001",
UnitType: "1"
};
//alert(JSON.stringify(input));
$.ajax({
async: true,
type: "GET",
contentType: "application/json; charset=utf-8",
dataType: "json",
url: "http://localhost:2878/Mtel_Profiler/Service.svc/getCommandStatus",
data: JSON.stringify(input),
success: function (userViewModel) {
var user = userViewModel;
alert(user);
},
error: function(msg) {
ServiceFailed(msg);
}
});
}
function ServiceSucceeded(msg)
{
alert('Sucess');
return false;
}
function ServiceFailed(result)
{
alert('Service call failed: ' + result.status + '' + result.statusText);
return false;
}
Can any one help to resolved this error. Thanks in advance.

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">

Streaming wcf service returning corrupt streamed file

I have a WCF service that returns a stream object. But for some reason i get a corrupt zip file back which i am streaming. All the code is below Please advise
Contract Code
[ServiceContract(Namespace = "http://schemas.acme.it/2009/04/01")]
public interface IFileTransferService
{
[OperationContract(IsOneWay = false)]
FileDownloadReturnMessage DownloadFile(FileDownloadMessage request);
[OperationContract()]
string HellowWorld(string name);
}
[MessageContract]
public class FileDownloadMessage
{
[MessageHeader(MustUnderstand = true)]
public FileMetaData FileMetaData;
}
[MessageContract]
public class FileDownloadReturnMessage
{
public FileDownloadReturnMessage(FileMetaData metaData, Stream stream)
{
this.DownloadedFileMetadata = metaData;
this.FileByteStream = stream;
}
[MessageHeader(MustUnderstand = true)]
public FileMetaData DownloadedFileMetadata;
[MessageBodyMember(Order = 1)]
public Stream FileByteStream;
}
[DataContract(Namespace = "http://schemas.acme.it/2009/04/01")]
public class FileMetaData
{
public FileMetaData(string [] productIDs, string authenticationKey)
{
this.ids = productIDs;
this.authenticationKey= authenticationKey;
}
[DataMember(Name = "ProductIDsArray", Order = 1, IsRequired = true)]
public string[] ids;
[DataMember(Name = "AuthenticationKey", Order = 2, IsRequired = true)]
public string authenticationKey;
}
SVC file code
public class DownloadCoverScan : IFileTransferService
{
public FileDownloadReturnMessage DownloadFile(FileDownloadMessage request)
{
FileStream stream = new FileStream(#"C:\Pictures.zip", FileMode.Open,
FileAccess.Read);
FileMetaData metaData= new FileMetaData(new string[] { "1", "2" },"asd");
FileDownloadReturnMessage returnMessage =
new FileDownloadReturnMessage(metaData,stream);
return returnMessage;
}
public string HellowWorld(string name)
{
return "Hello " + name;
}
}
Config code
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="DownloadCoverScanBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true" httpHelpPageEnabled="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="DownloadCoverScanBehavior" name="DownloadService.DownloadCoverScan">
<endpoint address="" name="basicHttpStream" binding="basicHttpBinding" bindingConfiguration="httpLargeMessageStream"
contract="DownloadService.IFileTransferService" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="httpLargeMessageStream" maxReceivedMessageSize="2147483647" transferMode="Streamed" messageEncoding="Mtom" />
</basicHttpBinding>
</bindings>
</system.serviceModel>
Client Code
FileMetaData metaData = new FileMetaData();
metaData.ProductIDsArray = new string[] { "1", "2" };
metaData.AuthenticationKey = "test";
FileDownloadMessage inputParam = new FileDownloadMessage(metaData);
FileTransferServiceClient obj = new FileTransferServiceClient();
FileDownloadReturnMessage outputMessage = obj.DownloadFile(inputParam);
Byte[] buffer = new Byte[8192];
int byteRead = outputMessage.FileByteStream.Read(buffer, 0, buffer.Length);
Response.Buffer = false;
Response.ContentType = "application/zip";
Response.AppendHeader("content-length", buffer.Length.ToString());
Response.AddHeader("Content-disposition", "attachment; filename=testFile.zip");
Stream outStream = Response.OutputStream;
while (byteRead > 0)
{
outStream.Write(buffer, 0, byteRead);
byteRead = outputMessage.FileByteStream.Read(buffer, 0, buffer.Length);
}
outputMessage.FileByteStream.Close();
outStream.Close();
I think the problem may be the Content-Length header from the response. You set it to 8192 while you actually don't know the length yet.
I'm not absolutely sure, however. Maybe it goes wrong earlier in the process. Maybe you can put some logging statement in your client code to be sure that you actually write all bytes to the output stream (by logging byteRead for example).
This could have to do with how you close your stream on the Server side. I had a project similar to this where the client was passing a stream in an Async call to the server, and the .zip file was corrupted sometimes. It turned out that I wasn't closing the stream on the client side properly resulting in an incomplete stream.
I didn't see code that showed the service closing the stream it sent on the service side.
I believe a stream won't complete properly unless it's closed. You can still read 0 bytes when it has nothing left to send though...

Resources