I have a WCF REST service that is reciving (POST) a string of base64 encoded json data. When I test this in fiddler2 I get a 400 bad request error
The problem seems to be with the lenght of the posted string but I don't get it cos in the web config I set the buffers and stuff to values that should be enugh. I don't know mybe the fiddlers buffer not enough but this would be odd I guess
In my testing I found out that the service actually fires if the request is a bit shorter then the actual full encoded object So I guess it has someting to do with the buffer but I fail to see the problem.
I got the encoded object back from the service as a get and tryed to put it back so the object is encoded correctly
Hope someone can help find the solution cos I think it is come detail I missed.
Fiddler call:
http://Server/WcfSyncDBService/SyncDBService.svc/AddTodoItems/PEFycmF5T2ZJdGVtcyB4bWxucz0iaHR0cDovL3NjaGVtYXMuZGF0YWNvbnRyYWN0Lm9yZy8yMDA0LzA3L1djZlN5bmNEQlNlcnZpY2UiIHhtbG5zOmk9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIj48SXRlbXM+PENhdGVnb3J5PlJlbWluZGVyPC9DYXRlZ29yeT48RGVzY3JpcHRpb24+UmVtaW5kZXI8L0Rlc2NyaXB0aW9uPjxJZD41PC9JZD48U3VtbWFyeT5UZXN0IDU8L1N1bW1hcnk+PC9JdGVtcz48L0FycmF5T2ZJdGVtcz4=
here is my code:
Interface:
[OperationContract(Name = "AddTodoItems")]
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare,
ResponseFormat = WebMessageFormat.Json, UriTemplate = "AddTodoItems/{content}")]
string AddTodoItems(string content);
Implementation:
public string AddTodoItems(string content)
{
var ret = String.Empty;
try
{
var data = DecodeFrom64(content);
ret = "Encoded:<" + content + ">";
ret = ret + "content:<" + data+">";
var ms = new MemoryStream(Encoding.UTF8.GetBytes(data));
var serializer = new DataContractSerializer(typeof(TodoItem[]));
var todoArray = (TodoItem[])serializer.ReadObject(ms);
var todoList = todoArray.ToList();
if (todoList.Count > 0)
{
var context = new SyncDBEntities();
foreach (var item in todoList)
{
var dbItem = (from i in context.todo where i.C_id == item.Id select i).First();
if (dbItem == null ) // insert
{
var itemAdd = new SyncDBmodel.todo();
itemAdd.C_id = item.Id;
itemAdd.category = item.Category;
itemAdd.summary = item.Summary;
itemAdd.description = item.Description;
context.AddTotodo(itemAdd);
context.SaveChanges();
}
else // update
{
dbItem.C_id = item.Id;
dbItem.category = item.Category;
dbItem.summary = item.Summary;
dbItem.description = item.Description;
context.SaveChanges();
}
}
}
}
catch (Exception e)
{
ret = ret+"Error:<"+e.Message+">";
ret = ret + "InnerException:<" + e.InnerException + ">";
}
finally
{
if (String.IsNullOrEmpty(ret))
ret = "OK";
}
return ret;
}
public bool DelTodoItems(string content)
{
bool ret = true;
try
{
var ms = new MemoryStream(Encoding.UTF8.GetBytes(content));
var serializer = new DataContractSerializer(typeof(TodoItem[]));
var todoArray = (TodoItem[])serializer.ReadObject(ms);
var todoList = todoArray.ToList();
if (todoList.Count > 0)
{
var context = new SyncDBEntities();
foreach (var item in todoList)
{
var dbItem = (from i in context.todo where i.C_id == item.Id select i).First();
if (dbItem != null) // delete
{
context.DeleteObject(dbItem);
context.SaveChanges();
}
}
}
}
catch (Exception)
{
ret = false;
}
return ret;
}
Web.config:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<httpRuntime maxRequestLength="524288" />
</system.web>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="StreamedRequestWebBinding"
bypassProxyOnLocal="true"
useDefaultWebProxy="false"
hostNameComparisonMode="WeakWildcard"
sendTimeout="10:15:00"
openTimeout="10:15:00"
receiveTimeout="10:15:00"
maxReceivedMessageSize="2147483647"
maxBufferSize="2147483647"
maxBufferPoolSize="2147483647"
transferMode="StreamedRequest">
<readerQuotas maxDepth="2147483647"
maxArrayLength="2147483647"
maxStringContentLength="2147483647"
maxBytesPerRead="2147483647"/>
<security mode="None"/>
</binding>
</webHttpBinding>
</bindings>
<services>
<service name="WcfSyncDBService.SyncDBService" behaviorConfiguration="ServiceBehaviour">
<endpoint
address =""
binding="webHttpBinding"
bindingConfiguration="StreamedRequestWebBinding"
contract="WcfSyncDBService.ISyncDBService"
behaviorConfiguration="web">
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehaviour">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
<scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll"/>
<dynamicTypes>
<add mimeType="text/*" enabled="true"/>
<add mimeType="application/xml" enabled="true" />
<add mimeType="application/json" enabled="true" />
<add mimeType="message/*" enabled="true"/>
<add mimeType="application/javascript" enabled="true"/>
<add mimeType="*/*" enabled="false"/>
</dynamicTypes>
<staticTypes>
<add mimeType="text/*" enabled="true"/>
<add mimeType="message/*" enabled="true"/>
<add mimeType="application/javascript" enabled="true"/>
<add mimeType="*/*" enabled="false"/>
</staticTypes>
</httpCompression>
</system.webServer>
<connectionStrings>
<add name="SyncDBEntities" connectionString="metadata=res://*/SyncDBmodel.csdl|res://*/SyncDBmodel.ssdl|res://*/SyncDBmodel.msl;provider=System.Data.SqlClient;provider connection string="data source=.;initial catalog=SyncDB;Persist Security Info=True;User ID=sa;Password=isql;multipleactiveresultsets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>
Related
I have a Windows app connecting to a WCF service that uses Entity Framework and is hosted in IIS. I get this error message when I try to return result of method in WCF service to my windows app:
An error occurred while receiving the HTTP response to http://localhost/BuyAndRechargeWcfService/BuyAndRechargeService.svc. > This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details.
Here is my web.config file of the WCF service:
<?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" />
<add key="DatabaseName" value="Recharge System"/>
<add key="ServerName" value="SAA"/>
<add key="UserId" value="sa"/>
<add key="Password" value="**"/>
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.7.2" />
<httpRuntime targetFramework="4.7.2" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<directoryBrowse enabled="true" />
</system.webServer>
<entityFramework>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
</configuration>
Here is exe.config file in Windows app:
<?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="DatabaseName" value="Recharge System"/>
<add key="ServerName" value="SAA"/>
<add key="UserId" value="sa"/>
<add key="Password" value="**"/>
<add key="DataSourceType" value="wcf"/>
</appSettings>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IBuyAndRechargeService" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost/BuyAndRechargeWcfService/BuyAndRechargeService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IBuyAndRechargeService"
contract="BuyAndRechargeService.IBuyAndRechargeService" name="BasicHttpBinding_IBuyAndRechargeService" />
</client>
</system.serviceModel>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<entityFramework>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
</configuration>
Here is service code:
using System;
using System.Collections.Generic;
using System.Data.Entity.Validation;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using EntityFarmework;
using Sedco.SelfService.Kiosk.SharedProject;
namespace BuyAndRechargeWcfService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "BuyAndRechargeService" in code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing this service, please select BuyAndRechargeService.svc or BuyAndRechargeService.svc.cs at the Solution Explorer and start debugging.
public class BuyAndRechargeService : IBuyAndRechargeService
{
private readonly BuyAndRechargeSystemModel _dataBaseEntities = new BuyAndRechargeSystemModel(new DatabaseConfiguration().GetWebConfiguration());
public dynamic HandleCustomer(string action, Dictionary<string, string> customerData)
{
dynamic result = null;
switch (action)
{
case "checkExistingPhoneNumber":
{
result= CheckExistingPhoneNumber(customerData);
break;
}
case "getCustomers":
{
result= GetCustomers();
break;
}
case "getCustomerInformation":
{
result= GetCustomerInformation(customerData);
break;
}
case "rechargeBalance":
{
result= RechargeBalance(customerData);
break;
}
case "getFilteredCustomers":
{
result= GetFilteredCustomers(customerData);
break;
}
case "deleteCustomers":
{
result= DeleteCustomers(customerData);
break;
}
case "checkIfNoCustomers":
{
result= CheckIfNoCustomers();
break;
}
case "addCustomer":
{
result= AddCustomer(customerData);
break;
}
case "getExpireDate":
{
result= GetExpireDate(customerData);
break;
}
case "editCustomer":
{
result= EditCustomer(customerData);
break;
}
default:
return false;
}
return result;
}
public dynamic HandlePackages(string action, Dictionary<string, string> packageInfo)
{
dynamic result = null;
switch (action)
{
case "getPackagesList":
result = _dataBaseEntities.Packages.Where(package => package.Type.Equals(packageInfo["packageType"]))
.Select(package => package.Name).ToList();
break;
case "addPackage":
try
{
Packages package = new Packages();
package.Name = packageInfo["packageName"];
package.Type = packageInfo["packageType"];
package.price = Int32.Parse(packageInfo["packagePrice"]);
_dataBaseEntities.Packages.Add(package);
_dataBaseEntities.SaveChanges();
result = true;
}
catch
{
result = false;
}
break;
case "getPackageTypeFromName":
result = _dataBaseEntities.Packages.Where(package => package.Name.Equals(packageInfo["packageName"]))
.Select(package => package.Type).FirstOrDefault();
break;
case "checkExistingPackages":
int packages = _dataBaseEntities.Packages.Where(package => package.Name == packageInfo["packageName"])
.Select(package => package.Name).Count();
result = packages != 0;
break;
}
return result;
}
private bool EditCustomer(Dictionary<string, string> customerData)
{
bool isEdited = false;
Customers customer =
_dataBaseEntities.Customers.FirstOrDefault(customerPhone =>
customerPhone.PhoneNumber.Equals(customerData["phoneNumber"]));
if (customer != null)
{
int packageId = _dataBaseEntities.Packages.Where(package => package.Name.Equals(customerData["packageName"]))
.Select(package => package.ID).FirstOrDefault();
customer.Name = customerData["editCustomerName"];
customer.BirthDate = customerData["editCustomerBirthDate"];
customer.PackageID = packageId;
_dataBaseEntities.SaveChanges();
isEdited = true;
}
else
{
isEdited = false;
}
return isEdited;
}
private DateTime GetExpireDate(Dictionary<string, string> customerData)
{
DateTime? expireDate = _dataBaseEntities.Customers
.Where(customer => customer.PhoneNumber.Equals(customerData["phoneNumber"]))
.Select(customer => customer.ExpireDate)
.FirstOrDefault();
return (DateTime)expireDate;
}
private bool AddCustomer(Dictionary<string, string> customerData)
{
bool result = false;
try
{
Customers customer = new Customers();
int packageId = _dataBaseEntities.Packages.Where(package => package.Name.Equals(customerData["packageName"]))
.Select(package => package.ID).SingleOrDefault();
int packagePrice = _dataBaseEntities.Packages.Where(package => package.Name.Equals(customerData["packageName"]))
.Select(package => package.price).FirstOrDefault();
string expireDateADateTime = DateTime.Now.AddMonths(3).ToString("yyyy-MM-dd HH:mm:ss");
DateTime expireDate = DateTime.ParseExact(expireDateADateTime, "yyyy-MM-dd HH:mm:ss",
CultureInfo.InvariantCulture);
customer.Name = customerData["customerName"];
customer.PhoneNumber = customerData["phoneNumber"];
customer.BirthDate = customerData["customerBirthDate"];
customer.PackageID = packageId;
customer.ExpireDate = expireDate;
customer.Balance = packagePrice;
_dataBaseEntities.Customers.Add(customer);
_dataBaseEntities.SaveChanges();
result = true;
}
catch (DbEntityValidationException e)
{
e.EntityValidationErrors.SelectMany(error => error.ValidationErrors).ToList().ForEach(
item => Console.WriteLine("{0} - {1}", item.PropertyName, item.ErrorMessage));
result = false;
}
catch (Exception ex)
{
result = false;
}
return result;
}
private bool CheckIfNoCustomers()
{
bool isNoCustomer = false;
int countOfCustomers = _dataBaseEntities.Customers.Count();
if (countOfCustomers == 0)
{
isNoCustomer = true;
}
else
{
isNoCustomer = false;
}
return isNoCustomer;
}
private bool DeleteCustomers(Dictionary<string, string> customerData)
{
bool isDeleted = true;
bool result = false;
List<Customers> deleteQuery = new List<Customers>();
foreach (string phoneNumber in customerData["phoneNumber"].Split(','))
{
Customers customerRow =
_dataBaseEntities.Customers.Single(customer => customer.PhoneNumber.Equals(phoneNumber));
deleteQuery.Add(customerRow);
if (customerRow != null)
{
isDeleted = true && isDeleted;
}
else
{
isDeleted = false && isDeleted;
break;
}
}
foreach (Customers delete in deleteQuery)
{
if (isDeleted)
{
_dataBaseEntities.Customers.Remove(delete);
_dataBaseEntities.SaveChanges();
result = true;
}
else
{
result = false;
}
}
return result;
}
private List<Customer> GetFilteredCustomers(Dictionary<string, string> customerData)
{
return _dataBaseEntities.Customers
.Where(customers =>
customers.Name.Contains(customerData["Search"]) ||
customers.PhoneNumber.Contains(customerData["Search"])).Select(customer => new Customer
{
CustomerName = customer.Name,
CustomerPhoneNumber = customer.PhoneNumber,
CustomerBirthdate = customer.BirthDate,
CustomerPackageName = customer.Packages.Name,
CustomerBalance = Convert.ToDecimal(customer.Balance)
}).ToList();
}
private string RechargeBalance(Dictionary<string, string> customerData)
{
Customers customerBalance = _dataBaseEntities.Customers.Single(customerPhoneNumber =>
customerPhoneNumber.PhoneNumber.Equals(customerData["PhoneNumber"]));
customerBalance.Balance = customerBalance.Balance + Convert.ToDecimal(customerData["Amount"]);
IFormatProvider culture = System.Globalization.CultureInfo.CurrentCulture;
customerBalance.ExpireDate = DateTime.ParseExact(DateTime.Now.AddMonths(1).ToString("dd-MM-yyyy"),
"dd-MM-yyyy", culture);
_dataBaseEntities.SaveChanges();
return customerBalance.Balance.ToString();
}
private Customer GetCustomerInformation(Dictionary<string, string> customerData)
{
return _dataBaseEntities.Customers
.Where(customers => customers.PhoneNumber.Equals(customerData["PhoneNumber"])).Select(
customer => new Customer
{
CustomerName = customer.Name,
CustomerPhoneNumber = customer.PhoneNumber,
CustomerBirthdate = customer.BirthDate,
CustomerPackageName = customer.Packages.Name,
CustomerBalance = (decimal)customer.Balance
}).Single();
}
private XmlNode[] GetCustomers()
{
var customers = _dataBaseEntities.Customers.Select(customerInfo => new Customer
{
CustomerName = customerInfo.Name,
CustomerPhoneNumber = customerInfo.PhoneNumber,
CustomerBirthdate = customerInfo.BirthDate,
CustomerPackageName = customerInfo.Packages.Name,
CustomerBalance = (decimal)customerInfo.Balance
}).ToList();
//Convert the List<Customer> object to an XmlNode[] object
XmlSerializer serializer = new XmlSerializer(typeof(List<Customer>));
using (StringWriter stringWriter = new StringWriter())
{
serializer.Serialize(stringWriter, customers);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(stringWriter.ToString());
return xmlDoc.ChildNodes.Cast<XmlNode>().ToArray();
}
}
private bool CheckExistingPhoneNumber(Dictionary<string, string> customerData)
{
return _dataBaseEntities.Customers.Count(
number => number.PhoneNumber == customerData["PhoneNumber"]) != 0;
}
}
}
When I try to debug the code I reach the return value of HandleCustomer method in WCF service and then I can't complete debugging (can't move to other statement the arrows is been disabled).
Please tell me if you want to provide you in any other parts of code
If possible, please check whether there is a record of 0 in the data found in the database.
When read in a program, it is converted to the corresponding enumeration type (enum), which does not define the enumeration value corresponding to 0. In this case, the conversion to an enumeration type does not throw an exception, and the value of the property remains 0 after the conversion. But when it is returned to the WCF client, the above exception is thrown.
The solution is to define the enumerated value corresponding to 0 in the enumerated type.
I'm trying to connect my WCF service in Xamarine Forms, but in runtime I am getting this error
For security reasons DTD is prohibited in this XML document. To enable DTD processing set the DtdProcessing property on XmlReaderSettings to Parse and pass the settings into XmlReader.Create method.
LoginWCFService.svc.cs
public class LoginWCFService : ILoginWCFService
{
public string LoginUserDetails(UserDetails userInfo)
{
string result = string.Empty;
bool res = false;
if (userInfo.uName!="" && userInfo.pWord != "" || userInfo.uName != null && userInfo.pWord != null)
{
result = "Login Successfull...";
}
else
{
res = false;
result = "Empty username or password";
}
return result.ToString();
}
}
ILoginWCFService.cs
[ServiceContract]
public interface ILoginWCFService
{
[OperationContract]
string LoginUserDetails(UserDetails UserInfo);
}
public class UserDetails
{
string UserName = string.Empty;
string Password = string.Empty;
[DataMember]
public string uName
{
get { return UserName; }
set { UserName = value; }
}
[DataMember]
public string pWord
{
get { return Password; }
set { Password = value; }
}
}
web.config
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.7.2" />
<httpRuntime targetFramework="4.7.2"/>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_ILoginWCFService" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://wcfapi.local/LoginWCFService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ILoginWCFService"
contract="WcfService_Omss.ILoginWCFService" name="BasicHttpBinding_ILoginWCFService" />
</client>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
Consuming WCF in Xamarine Form
LoginPage.xaml.cs
WCFServiceReference.LoginWCFServiceClient client = new LoginWCFServiceClient();
client.Open();
UserDetails user = new UserDetails();
user.uName = Uname.Text.ToString();
user.pWord = Pass.Text.ToString();
var res = client.LoginUserDetails(user); //Getting error here
if (res == "Login Successfull...")
await DisplayAlert("Message", "Login Successfull...", "Cancel");
else
await DisplayAlert("Message", "Login failed...", "Cancel");
client.Close();
Can anyone please tell me where I have to do changes to resolve this error?
This error has nothing to do with the wcf service. As the message says, set the DtdProcessing property on XmlReaderSettings to Parse and pass the settings to the XmlReader.Create method. You can refer to the code below.
https://learn.microsoft.com/en-us/dotnet/api/system.xml.xmlreadersettings.dtdprocessing?view=net-6.0
using System;
using System.Xml;
using System.Xml.Schema;
using System.IO;
public class Sample {
public static void Main() {
// Set the validation settings.
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Parse;
settings.ValidationType = ValidationType.DTD;
settings.ValidationEventHandler += new ValidationEventHandler (ValidationCallBack);
// Create the XmlReader object.
XmlReader reader = XmlReader.Create("itemDTD.xml", settings);
// Parse the file.
while (reader.Read());
}
// Display any validation errors.
private static void ValidationCallBack(object sender, ValidationEventArgs e) {
Console.WriteLine("Validation Error: {0}", e.Message);
}
}
I have a created a WCF service which is consumed by android. It returns DataRows in json. As,
Web.config
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="httpBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="WcfAndroid.Service1">
<endpoint address=""
behaviorConfiguration="httpBehavior"
binding="webHttpBinding"
contract="WcfAndroid.IService1" />
</service>
</services>
<protocolMapping>
<add binding="webHttpBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
Service Interface IService1 :
<OperationContract()> _
<WebInvoke(Method:="POST", UriTemplate:="GetEmp", ResponseFormat:=WebMessageFormat.Json)> _
Function GetEmp(ByVal EmpId As String) As DataTable
Service Class Service1 :
Public Function GetEmp(ByVal EmpId As String) As DataTable
Dim table As New DataTable("mytable")
table.Columns.Add("Result", GetType(String))
table.Columns.Add("acc", GetType(String))
table.Columns.Add("name", GetType(String))
table.Columns.Add("paid", GetType(Double))
'' Using EmpId for Fetching data from Database
table.Rows.Add("True", "1", "Employee1", 5000)
table.Rows.Add("True", "2", "Employee2", 2000)
Return table
End Function
EmpId is unique id for every employee. I am getting the details from Sql Server database. For testing i have sent 2 rows manually.
In android app for WebGet i have used :
public static JSONObject requestWebService(String serviceUrl) {
HttpURLConnection urlConnection = null;
try {
URL urlToRequest = new URL(serviceUrl);
urlConnection = (HttpURLConnection)
urlToRequest.openConnection();
int statusCode = urlConnection.getResponseCode();
if (statusCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
// handle unauthorized
} else if (statusCode != HttpURLConnection.HTTP_OK) {
// handle any other errors
}
InputStream in = new BufferedInputStream(
urlConnection.getInputStream());
String ss=getResponseText(in);
return new JSONObject(ss);
} catch (MalformedURLException e) {
// URL is invalid
} catch (SocketTimeoutException e) {
// data retrieval or connection timed out
} catch (IOException e) {
// could not read response body
// (could not create input stream)
} catch (JSONException e) {
// response body is no valid JSON string
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return null;
}
But i don't know how to POST with EmpId and getDataRows.
I have to consume this service in android app. I am using HttpURLConnection.
How to post using HttpURLConnection and getDatarows (json format) ?
You can use OutputStreamWriter as :
public static JSONObject PostWebService(String serviceUrl) {
HttpURLConnection urlConnection = null;
try {
// create connection
URL urlToRequest = new URL(serviceUrl);
urlConnection = (HttpURLConnection)
urlToRequest.openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setRequestProperty("Content-Type", "application/json");
OutputStreamWriter out = new OutputStreamWriter(urlConnection.getOutputStream());
out.write("EmpID2016");
// You can write json also // Uncomment
// JSONObject jsonParam = new JSONObject();
// jsonParam.put("EmpID", "25");
// jsonParam.put("description", "Employer");
// jsonParam.put("authorized", "true");
// out.write(jsonParam.toString());
out.close();
int statusCode = urlConnection.getResponseCode();
if (statusCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
// handle unauthorized (if service requires user login)
} else if (statusCode != HttpURLConnection.HTTP_OK) {
// handle any other errors, like 404, 500,..
}
// create JSON object from content
InputStream in = new BufferedInputStream(
urlConnection.getInputStream());
String ss=getResponseText(in);
return new JSONObject(ss);
} catch (MalformedURLException e) {
} catch (SocketTimeoutException e) {
} catch (IOException e) {
} catch (JSONException e) {
// response body is no valid JSON string
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return null;
}
I'm wanting my web service to return JSON not XML, currently it's returning JSON wrapped in XML. View the source of my URL http://soulappvm.cloudapp.net/SAService/Service.svc/userlist produces the following...
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">[{"Name":"Daniel1user","Password":"40d5e24c5c906103a980ec7c69c100c5","Address":"123 st"},{"Name":"Daniel2user","Password":"90a1587cbe37d4a2a128ce758f338587","Address":"1234 st"},{"Name":"Daniel3user","Password":"f97c27c65d3af0d18657cbae16f9d57e","Address":"ccc"},{"Name":"user1user","Password":"def907bec025cd03bf738c3612bd7926","Address":"ds"},{"Name":"user2user","Password":"0fa04e1c4a5720195b106df9e746a72b","Address":"ff"}]</string>
Is there simple way to get it to just return JSON? I have tried ResponseFormat = WebMessageFormat.Json but that did not work.
IService
namespace SoulInfoService
{
[ServiceContract(SessionMode = SessionMode.Allowed, Namespace = "http://mmmkay95989.wix.com/bb2soulinfo")]
public interface IService
{
[OperationContract]
[WebGet(UriTemplate = "id")]
//[AspNetCacheProfile("CacheFor1200Seconds")]
string ServiceID();
[OperationContract]
[WebGet(UriTemplate = "version")]
//[AspNetCacheProfile("CacheFor1200Seconds")]
string Version();
[OperationContract]
[WebGet(UriTemplate = "userlist", ResponseFormat = WebMessageFormat.Json)]
[AspNetCacheProfile("CacheFor1200Seconds")]
string UserList();
[OperationContract]
[WebGet(UriTemplate = "usersearch?term={term}")]
User[] UserSearch(string term);
[OperationContract]
[WebGet(UriTemplate = "soulimg?id={id}")]
Stream SoulImage(string id);
[OperationContract]
[WebInvoke(Method = "OPTIONS", UriTemplate = "*")]
void GetOptions();
} // interface
}
Service
namespace SoulInfoService
{
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service : IService
{
public Service()
{
serviceID = Guid.NewGuid();
} // Service
public string ServiceID()
{
string rval = "";
rval = serviceID.ToString();
return rval;
} // ServiceID
public string Version()
{
return "1.0.0";
} // Version
public void GetOptions()
{
} // GetOptions
public string UserList()
{
User[] rval = null;
using (var sqlCommand = new SQLiteCommand("SELECT * FROM Users"))
{
rval = GetUsers(sqlCommand);
}
return JsonConvert.SerializeObject(rval);
//return rval;
} // UserList
public User[] UserSearch(string term)
{
User[] rval = null;
#if SANITY_CHECK
term = Sanitize(term);
#endif
string sqlString = String.Format("SELECT * FROM Users WHERE username LIKE '%{0}%'", term);
using (var sqlCommand = new SQLiteCommand(sqlString))
{
rval = GetUsers(sqlCommand);
}
for (int i = 0; i < rval.Length; i++)
{
System.Diagnostics.Debug.WriteLine("value: " + rval[i].Name);
}
return rval;
} // UserSearch
public Stream SoulImage(string id)
{
string categoryFolder = "/Souls/";
return GetImage(id, categoryFolder);
} //SoulImage
private Stream GetImage(string id, string categoryFolder)
{
string mimeType = "image/jpeg";
string fileExtension = "jpg";
ConfigReader config = new ConfigReader();
string dataRoot = config.GetString(CONFIG_DATA_ROOT, #"C:/");
string img = dataRoot + "/Images/" + categoryFolder + "/" + Path.ChangeExtension(id, fileExtension);
MemoryStream ms = null;
if (!File.Exists(img))
{
mimeType = "image/gif";
fileExtension = "gif";
img = dataRoot + "/Images/" + categoryFolder + "/" + Path.ChangeExtension(id, fileExtension);
if (!File.Exists(img))
{
mimeType = "image/png";
fileExtension = "png";
img = dataRoot + "/Images/" + categoryFolder + "/" + Path.ChangeExtension(id, fileExtension);
if (!File.Exists(img))
{
img = dataRoot + "/Images/Default.png";
}
}
}
ms = new MemoryStream(File.ReadAllBytes(img));
WebOperationContext.Current.OutgoingResponse.ContentType = mimeType;
return ms;
} // GetImage
private User[] GetUsers(SQLiteCommand command)
{
var list = new List<User>();
try
{
using (SQLiteConnection dbConnection = OpenDBConnection())
{
command.Connection = dbConnection;
using (SQLiteDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
var b = new User()
{
//Id = reader["TextId"].ToString(),
Name = reader["Username"].ToString(),
Password = reader["Password"].ToString(),
Address = reader["Address"].ToString(),
};
list.Add(b);
}
reader.Close();
}
dbConnection.Close();
}
}
catch (Exception ex)
{
string tmp = ex.Message;
}
return list.ToArray();
} // GetUsers
private static string Sanitize(string term)
{
Regex rgx = new Regex(#"[^\p{L}\p{N} ]+"); // \p{L} matches Unicode letters while \p{N} matches Unicode digits
term = rgx.Replace(term, ""); // Strip anything that isn't a letter or digit
return term;
} // Sanitize
private SQLiteConnection OpenDBConnection()
{
ConfigReader config = new ConfigReader();
string dataRoot = config.GetString(CONFIG_DATA_ROOT, #"C:/");
string dataDb = dataRoot + "/" + config.GetString(CONFIG_DATABASE, #"");
//string dataDb = dataRoot + "/" + databaseID;
string connectionString = String.Format("Data Source={0};Version=3;", dataDb);
SQLiteConnection dbConnection = new SQLiteConnection(connectionString);
dbConnection.Open();
return dbConnection;
} // OpenDBConnection
/// <summary>
/// Adds access control headers to service methods. One will need to add this when using
/// the Development Server which does not use system.webServer section of the Web.config
/// file and thus add the custom headers in there.
/// </summary>
private void AddAccessControlHeaders()
{
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Headers", "Authorization, Content-Type");
} // AddAccessControlHeaders
private readonly string CONFIG_DATA_ROOT = "DataRoot";
private readonly string CONFIG_DATABASE = "Database";
private readonly string CONFIG_REALM = "Realm";
private readonly Guid serviceID;
} // class
}
Web.config
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="DataRoot" value="C:/Users/delm959/Documents/Database"/>
<add key="Database" value="TestDatabase.db"/>
<add key="Realm" value="Boutique Cassee"/>
</appSettings>
<!--
For a description of web.config changes for .NET 4.5 see http://go.microsoft.com/fwlink/?LinkId=235367.
The following attributes can be set on the <httpRuntime> tag.
<system.Web>
<httpRuntime targetFramework="4.5" />
</system.Web>
-->
<system.web>
<customErrors mode="Off"/>
<compilation debug="true" targetFramework="4.5"/>
<caching>
<outputCacheSettings>
<outputCacheProfiles>
<add name="CacheFor1200Seconds" duration="1200" varyByParam="none" varyByHeader="Accept"/>
</outputCacheProfiles>
</outputCacheSettings>
</caching>
<pages controlRenderingCompatibilityVersion="4.0"/>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above 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"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="DefaultEndPointBehavior">
<dataContractSerializer maxItemsInObjectGraph="10000"/>
</behavior>
<behavior name="RESTEndPointBehavior">
<webHttp helpEnabled="true" automaticFormatSelectionEnabled="true"/>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="WebHttpBindingConfig">
<!-- Comment out the security for HTTP; uncomment the security for HTTPS -->
<!--<security mode="Transport">
<transport clientCredentialType="None" />
</security>-->
</binding>
</webHttpBinding>
<basicHttpBinding>
<binding name="BasicHttpBindingConfig">
<readerQuotas/>
<!--
<security mode="None"/>
-->
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="SoulInfoService.Service">
<endpoint address="" behaviorConfiguration="RESTEndPointBehavior"
binding="webHttpBinding" bindingConfiguration="WebHttpBindingConfig"
bindingNamespace="http://www.example.org/Samples" contract="SoulInfoService.IService" />
<endpoint address="soap" behaviorConfiguration="DefaultEndPointBehavior"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBindingConfig"
bindingNamespace="http://www.example.org/Samples" contract="SoulInfoService.IService" />
<endpoint address="mex" binding="mexHttpBinding" bindingNamespace="http://www.example.org/Samples"
contract="IMetadataExchange" />
</service>
</services>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true"/>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*"/>
<add name="Access-Control-Request-Method" value="OPTIONS, GET, POST"/>
<add name="Access-Control-Allow-Credentials" value="true"/>
<add name="Access-Control-Allow-Headers" value="Authorization, Content-Type"/>
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
This is a quite good tutorial how to create RESTful service with WCF which uses JSON formatter.
http://www.codeproject.com/Articles/105273/Create-RESTful-WCF-Service-API-Step-By-Step-Guide
I have client(Windows Phone) and i have REST Service.The problem is this: I am sending a POST request in which a variable JSON string service processes it, and the answer comes:
"{StatusCode: 404, ReasonPhrase: '', Version: 0.0, Content: System.Net.Http.StreamContent, Headers:{ Content-Length: 0}}"
I have a very long time trying to figure out. Without the help of all. And so, all the stages:
1) The variable that I post:
"{"Category_id":1002,"Country_id":null,"City_id":null,"Areas_id":null,"Gender_user":null,"DateAnnouncing":null,"MinDateBirthday":null,"MaxDateBirthday":null,"Popular":null,"DateSort":null}"
2) Calling Method
public static async Task<string> ServiceCalledWithJson( string MethodName, AnnFilter customObject)
{
string ServiceURI = GetServiceHost() + MethodName;
var httpClient = new HttpClient();
var result = JsonConvert.SerializeObject(new { filter = customObject });
var request = new StringContent(result, Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync(ServiceURI, request);
string content = await response.Content.ReadAsStringAsync();
return content;
}
3) In Interface
[OperationContract]
[WebInvoke(Method = "POST",ResponseFormat =WebMessageFormat.Json,BodyStyle =WebMessageBodyStyle.WrappedRequest)]
List<Announcing> GetAnnouncingFilter(AnnFilter filter);
4)Function
public List<Announcing> GetAnnouncingFilter(AnnFilter filter)
{
var json = JsonConvert.SerializeObject(filter);
Logger.WriteToFile_Json(json);
List < Announcing > listAnnonc = new List<Announcing>();
Announcing annonc = new Announcing();
DataTable table = new DataTable();
table = AnnouncingFilter.GetAnnouncingFilter(filter);
foreach(DataRow row in table.Rows)
{
try
{
annonc.Announcing_id = int.Parse(row["Announcing_id"].ToString());
annonc.Name_Announcing = row["Name_Announcing"].ToString();
annonc.Name_City = row["City_Name"].ToString();
listAnnonc.Add(new Announcing() {Announcing_id=annonc.Announcing_id,Name_Announcing=annonc.Name_Announcing,Name_City =annonc.Name_City });
}
catch (Exception ex)
{
Logger.CreateLog(ex);
throw ex;
}
}
var slem = "";
slem = JsonConvert.SerializeObject(listAnnonc);
Logger.WriteToFile_Json(slem);
return listAnnonc;
5)Logging
{"Category_id":1002,"Country_id":null,"City_id":null,"Areas_id":null,"Gender_user":null,"DateAnnouncing":null,"MinDateBirthday":null,"MaxDateBirthday":null,"Popular":null,"DateSort":null
[{"Name_City":"Киев","Announcing_id":1,"Name_Announcing":"Прогулки","Phone_Announcing":null,"Date_Announcing":"0001-01-01T00:00:00","Info_Announcing":null,"Categories_id":0,"User_id":0,"City_id":0,"Areas_id":null,"AreasOfCity":null,"Categories":null,"Cities":null,"UserList":null,"Favorite_Announcing":[],"Selected_Announcing":[]}]
6) Web config:
<endpointBehaviors>
<behavior name="restBehavior">
<webHttp helpEnabled="true" defaultOutgoingResponseFormat="Json"/>
</behavior>
</endpointBehaviors>
<service behaviorConfiguration="MyBehavior" name="Searching.BE.Service.WCFRESTService">
<endpoint address="" behaviorConfiguration="restBehavior" binding="webHttpBinding"
contract="Searching.BE.Service.IWCFRESTService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<endpoint address="net" binding="netHttpBinding" contract="Searching.BE.Service.IWCFRESTService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<webHttpBinding>
<binding name="webhttp"
bypassProxyOnLocal="true"
useDefaultWebProxy="false"
hostNameComparisonMode="WeakWildcard"
sendTimeout="10:15:00"
openTimeout="10:15:00"
receiveTimeout="10:15:00"
maxReceivedMessageSize="2147483647"
maxBufferSize="2147483647"
maxBufferPoolSize="2147483647"
transferMode="StreamedRequest">
<readerQuotas maxArrayLength="2147483647"
maxStringContentLength="2147483647" />
<security mode="None">
<transport clientCredentialType="None">
</transport>
</security>
</binding>
</webHttpBinding>