WCF + Silverlight + HttpContext.Current.Session is null - silverlight

my problem....
i am tryingo to access session from Silverlight and WCF basicHttpBinding...
i saw some posts where it's possible (http://www.dotnetspider.com/Silverlight-Tutorial-317.aspx)
Mys cenario is:
Silvelright 4 FW 3.5
in web.config i have
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="ViewModelDemo.Web.Service1Behavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="ViewModelDemo.Web.Service1Behavior" name="ViewModelDemo.Web.Service1">
<endpoint address="" binding="basicHttpBinding" contract="ViewModelDemo.Web.Service1">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
and my service:
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class Service1
{
[OperationContract]
publicvoid Test()
{
var session = System.Web.HttpContext.Current.Session;
}
}
and it''s call
var client = new Service1Client();
client.GetUserMacroFunctionsCompleted += new System.EventHandler<GetUserMacroFunctionsCompletedEventArgs>(client_GetUserMacroFunctionsCompleted);
client.GetUserMacroFunctionsAsync();
void client_GetUserMacroFunctionsCompleted(object sender, GetUserMacroFunctionsCompletedEventArgs e)
{
var test = ((Collection<Function>)e.Result);
}
HttpContext.Current is always null!
Any suggestions?

Yes HttpContext must be always null because your service configuration doesn't setup ASP.NET compatibility and your service doesn't require ASP.NET compatibility.
Add this to your configuration:
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
And change AspNetCompatibilityRequirements so that your service cannot be hosted without former configuration:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]

This link probably to help you.
http://blogs.msdn.com/b/sajay/archive/2006/08/03/687361.aspx
aspNetCompatibilityEnabled="true" doesn't help me till I set allowCookies="true" on the client binding configuration.

Update your web.config file to include
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
This should work, or else also change the AspNetCompatibilityRequirementsMode attribute on the contract to Required.

Related

Adding Web API as Application to Website in IIS, where does Frontend point to?

I have two separate processes running for my website. The frontend is reactjs and the backend is asp.net core 6.
I have a reactjs website running on localhost:9000 on IIS on a server.
I've added the .net web api published files to the above website as an application with it's own application pool.
In the .env REACT_APP_API_URL: I don't know how to point to the API, before i just used localhost:5000, how do I change this to use the application url?
Tried: */api/controllername, localhost/api/controllername, IPADDRESS/api/controllername,
COMPUTERNAME/api/controllername etc.
Here is the Program.cs
using api;
using api.Services;
using Microsoft.AspNetCore.Authentication.Cookies;
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseIIS();
builder.Services.Configure<IISServerOptions>(options =>
{
options.AutomaticAuthentication = false;
});
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowOrigin",
options =>
{
options.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod();
});
});
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.Cookie.Name = "Project.Cookies";
options.ExpireTimeSpan = TimeSpan.FromHours(12);
options.SlidingExpiration = true;
options.LoginPath = "/User/Login";
options.LogoutPath = "/User/Logout";
options.Cookie.IsEssential = true;
});
builder.Services.AddDbContext<DbDataContext>();
builder.Services.AddScoped<IProjectService, ProjectService>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment() || app.Environment.IsProduction())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseCors();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
Here is the web.config for the backend:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\api.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
</system.webServer>
</location>
</configuration>
<!--ProjectGuid: -->
And here is the web.config for the reactjs frontend:
<?xml version="1.0"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="React Routes" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
I'm in over my head on how to get these talking to each other.
I can run the dotnet from the commandline and have reactjs talk to that localhost on the server (this wont work when connecting to the website from outside the server). But I need these working in IIS.
Any help would be greatly appreciated.
The front end and the backend application should use same port. In your react project, you should use something like const baseUrl = document.getElementsByTagName('base')[0].getAttribute('href'); or process.env.PORT. And your frontend will start with port which you create the main website. You can find it like below.
The main application and virtual application host in same site with different application. And they also should use same port. You can check my test result.
And you can open the frontend application by clicking the Browse *:8031 in the right panel in my picture.
You can access your api application via https://localhost:8031/api/{apiname or controller/action}.
In your case, it should be http://localhost:port/{hidden by red pen}api/controllername.

What's wrong with my connection string (can not access it through ConfiguratioManager)?

I'm trying to connect to Azure SQL, but I get error The underlying provider failed on Open
I discovered that I have put connection string in the wrong app.config - moved it to the executable project's app.config, but still the same result
When I check ConfigurationManager.ConnectionStrings["AzureDatabase"] it returns null. And when I try to connect it just uses default SQLExpress.
When I check build folder of my executable application - there is an <app_name>.exe.config file with "AzureDatabase". I'm stuck on where to search from here
This is my DbContext class
[DbConfigurationType(typeof(AzureDbConfiguration))]
public class ProductDbContext : DbContext
{
//Db sets
static MyContext()
{
//I don't want to change database from code
Database.SetInitializer<MyContext>(null);
}
public MyContext() : base("AzureDatabase") //this is my connectionstring
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//some mappings
}
}
This is AzureDbConfiguration
public class AzureDbConfiguration : DbConfiguration
{
public AzureDbConfiguration()
{
SetExecutionStrategy("System.Data.SqlClient", () => new SqlAzureExecutionStrategy(2, TimeSpan.FromSeconds(10)));
}
}
This is my app.config file
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="AzureDatabase"
connectionString="Server=tcp:xxx.database.windows.net,1433;Initial Catalog=xxx;Persist Security Info=False;User ID=xxxx;Password=xxxxx;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" providerName="System.Data.SqlClient"/>
</connectionStrings>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="mssqllocaldb" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
</configuration>
Any ideas on what's wrong here?
It turns out the problem was that I was trying to work with app.config from Class library (I was trying to create an integration tests)
One of potential solutions is to create a separate settings file for Class library. You can read about it in this StackOverflow post

Mule - Object to parameters in Database

I have this mule flow:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:db="http://www.mulesoft.org/schema/mule/db" xmlns:json="http://www.mulesoft.org/schema/mule/json" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans" version="EE-3.5.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd
http://www.mulesoft.org/schema/mule/db http://www.mulesoft.org/schema/mule/db/current/mule-db.xsd">
<spring:beans>
<spring:bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<spring:property name="locations">
<spring:list>
<spring:value>configSQL.properties</spring:value>
</spring:list>
</spring:property>
</spring:bean>
</spring:beans>
<db:generic-config name="BBDD_USER" doc:name="Generic Database Configuration" driverClassName="net.sourceforge.jtds.jdbc.Driver"
url="${sql.url}/${sql.database};user=${sql.username};password=${sql.password}"/>
<flow name="sincro-sql" doc:name="sincro-sql">
<http:inbound-endpoint exchange-pattern="one-way" host="localhost" port="8042" doc:name="HTTP"/>
<logger message="#[message.payloadAs(java.lang.String)]" level="INFO" doc:name="JSON"/>
<json:json-to-object-transformer doc:name="JSON to Object" returnClass="json.database.object.Data"/>
<db:stored-procedure config-ref="BBDD_USER" doc:name="Data" source="json.database.object.Data" streaming="true">
<db:parameterized-query><![CDATA[{ CALL dbo.ExecSQL(:table_name, :field_name) }]]></db:parameterized-query>
<db:in-param name="field_name" type="VARCHAR" value="field_test"/>
<db:in-param name="table_name" type="VARCHAR" value="table_test"/>
</db:stored-procedure>
</flow>
</mule>
It receives a JSON that I transform to object with a class that contains:
#JsonAutoDetect
public class Data{
private String table_name;
private String field_name;
public void setTableName(String table_name) {
this.table_name= table_name;
}
public String getTableName() {
return table_name;
}
public void setFieldName(String field_name) {
this.field_name= field_name;
}
public String getFieldName() {
return field_name;
}
}
And finally, I call to my database. How can I assign, for example, the property about the table name from the class to the parameter in the database element?
For example,
<db:in-param name="table_name" type="VARCHAR" value="PROPERTY OF CLASS"/>
Use MEL(Mule Expression Langauge) and standard Java method invocation. As Data is you payload, use #[payload.table_name] MEL will automatically use the getter for that field.

Decompressing Web Api response

I am compressing web Api responses with following config
<system.webServer>
<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/*" enabled="true" />
<add mimeType="*/*" enabled="false" />
</dynamicTypes>
<staticTypes>
<add mimeType="text/*" enabled="true" />
<add mimeType="application/*" enabled="true" />
<add mimeType="*/*" enabled="false" />
</staticTypes>
</httpCompression>
<urlCompression doStaticCompression="true" doDynamicCompression="true" />
Now when i consume this in a Win Form applications and try to do the follwoing
var rawData = await response.Content.ReadAsStringAsync();
var deserializedData = JsonConvert.DeserializeObject<Employees[]>(rawData).ToList();
it fails on
var deserializedData = JsonConvert.DeserializeObject(rawData).ToList();
the Error message is
{"Unexpected character encountered while parsing value: . Path '', line 0, position 0."}
I guess this is due to the fact that content is gziped and not being deserialized. Can anyone suggest a solution ? This works locally fine as local IIS is not gzip enabled
You need to enable automatic GZip decompression:
var handler = new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip };
var client = new HttpClient(handler);

Error while using iterator mediator in wso2esb

I'm using wso2esb 4.7.0 and wso2dss 3.1.0.My scenario is i wish to select all partybranch regarding particular clientid. For that purpose i have fire a query like :
select partybranchid,clientid from mpartybranch where clientid = 473906852857651
and it gives me list of 2 records like :
partybranchid clientid
-2500000000 473906852857651
796243010946586 473906852857651
I wish to split these two and find out address regarding each of them.I have use following query in dss that works seperately for me is :
select * from address where partybranchid = ? and clientid =?
Now i have use iterator mediator in wso2esb to implement this in single click.My configuration is :
<iterate xmlns:f="http://ws.wso2.org/dataservice" continueParent="true" preservePayload="true" expression="//f:Datalist" id="iterate1" sequential="true">
<target>
<sequence>
<property xmlns:s="http://ws.wso2.org/dataservice" name="partybranchid1" expression="//s:partybranchid/text()" scope="default" type="STRING"/>
<property xmlns:s="http://ws.wso2.org/dataservice" name="latitude" expression="get-property('latitude')"/>
<property xmlns:s="http://ws.wso2.org/dataservice" name="longitude" expression="get-property('longitude')"/>
<property xmlns:s="http://ws.wso2.org/dataservice" name="radius" expression="get-property('radius')"/>
<payloadFactory media-type="xml">
<format>
<p:select_addresses_op xmlns:p="http://ws.wso2.org/dataservice">
<p:latitude>$1</p:latitude>
<p:longitude>$2</p:longitude>
<p:radius>$3</p:radius>
<p:objectid>$4</p:objectid>
</p:select_addresses_op>
</format>
<args>
<arg xmlns:s="http://ws.wso2.org/dataservice" expression="get-property('latitude')" evaluator="xml"/>
<arg xmlns:s="http://ws.wso2.org/dataservice" expression="get-property('longitude')" evaluator="xml"/>
<arg xmlns:s="http://ws.wso2.org/dataservice" expression="get-property('radius')" evaluator="xml"/>
<arg xmlns:s="http://ws.wso2.org/dataservice" expression="get-property('partybranchid1')" evaluator="xml"/>
</args>
</payloadFactory>
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
<property name="messageType" value="application/json" scope="axis2"/>
<send receive="spatial_seq3">
<endpoint>
<address uri="http://localhost:9764/services/Aspatialtrial_Dataservice/" format="soap11"/>
</endpoint>
</send>
</sequence>
</target>
</iterate>
This configuration is working but doesn't give expected output.Following are the outputs at client side and server side:
At server side(ESB) output :
[2014-09-25 09:52:30,941] INFO - LogMediator To: /services/spatial_proxy_test, MessageID: urn:uuid:c91c22b6-245f-49f7-bf30-65561c87050f, Direction: request, userid = null, username = vikash|214057357158656, password = gbadmin
[2014-09-25 09:52:30,953] INFO - TimeoutHandler This engine will expire all callbacks after : 120 seconds, irrespective of the timeout action, after the specified or optional timeout
[2014-09-25 09:52:31,286] INFO - LogMediator To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:9fa3c017-27f5-405e-a11b-33a9fa9a8f44, Direction: response, kk = true, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Body><ResponseJSON><Body><Datalist><Authentication>true</Authentication></Datalist></Body></ResponseJSON></soapenv:Body></soapenv:Envelope>
[2014-09-25 09:52:32,148] INFO - LogMediator FORCE_ERROR_ON_SOAP_FAULT = true, partybranchid1 = -2500000000796243010946586, latitude = 18.975, longitude = 72.8258, radius = 10
[2014-09-25 09:52:32,344] INFO - LogMediator To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:c635aa03-36ac-4af7-8b01-9bb31b35f4ef, Direction: response, Datalist values logged = <Datalist xmlns="http://ws.wso2.org/dataservice"><addressid>457492199890748451</addressid><geocode>POINT(18.975 72.8258)</geocode></Datalist>, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><DataCollection xmlns="http://ws.wso2.org/dataservice"><Datalist><addressid>457492199890748451</addressid><geocode>POINT(18.975 72.8258)</geocode></Datalist></DataCollection></soapenv:Body></soapenv:Envelope>
[2014-09-25 09:52:32,345] INFO - LogMediator To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:e77556c0-b722-4f91-879b-1cbb4ae20aec, Direction: response, Datalist values logged = <Datalist xmlns="http://ws.wso2.org/dataservice"><addressid>456211760366486560</addressid><geocode>POINT(19.0769048 72.8570555)</geocode></Datalist><Datalist xmlns="http://ws.wso2.org/dataservice"><addressid>456217678470710306</addressid><geocode>POINT(18.975 72.8258)</geocode></Datalist>, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><DataCollection xmlns="http://ws.wso2.org/dataservice"><Datalist><addressid>456211760366486560</addressid><geocode>POINT(19.0769048 72.8570555)</geocode></Datalist><Datalist><addressid>456217678470710306</addressid><geocode>POINT(18.975 72.8258)</geocode></Datalist></DataCollection></soapenv:Body></soapenv:Envelope>
at client side output
{"ResponseJSON":{"Body":{"Datalist":{"addressid":"457492199890748451","geocode":"POINT(18.975 72.8258)"}},"Status":"200","Total":"1.0"}}
And request is :
curl -v -H "Accept: application/json" -H "Content-Type:application/json" -H "ModifiedOn:0" -H "username:vikash|214057357158656" -H "password:gbadmin" -d '{"usercode":"suresh","clientid":"473906852857651","longitude":"72.8258","radius":"10","latitude":"18.975"}' http://youtility-desktop:8282/services/spatial_proxy_test
Server side log shows that it is iterating fine but at client side gives response of one iteration only.Why so?IS their any changes regarding sequence options like ContinueParent or preservepayload etc..?Please let me know..
I test your scenario last night, my proxy look like this:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="AddressProxy"
transports="https http"
startOnLoad="true"
trace="disable">
<description/>
<target>
<inSequence>
<property xmlns:p="http://www.example.org/Address/"
name="clientid"
expression="//p:getAddress/clientid"
scope="default"
type="STRING"/>
<sequence key="conf:/sequencesStackOverFlow/getmpartybranch"/>
</inSequence>
<outSequence>
<aggregate>
<completeCondition>
<messageCount min="-1" max="2"/>
</completeCondition>
<onComplete xmlns:add="http://ws.wso2.org/dataservice"
expression="//add:Addresses/add:Address">
<send/>
</onComplete>
</aggregate>
</outSequence>
</target>
<publishWSDL key="conf:/wsdls/Address.wsdl"/>
</proxy>
And the sequences used in the insequence:
conf:/sequencesStackOverFlow/getmpartybranch
<sequence xmlns="http://ws.apache.org/ns/synapse">
<payloadFactory media-type="xml">
<format>
<dat:getmpartybranch xmlns:dat="http://ws.wso2.org/dataservice">
<dat:clientid>$1</dat:clientid>
</dat:getmpartybranch>
</format>
<args>
<arg xmlns:ns="http://org.apache.synapse/xsd" expression="get-property('clientid')" evaluator="xml"></arg>
</args>
</payloadFactory>
<send receive="conf:/sequencesStackOverFlow/iterOvermpartybranch">
<endpoint>
<address uri="http://127.0.0.1:5555/services/mpartybranch"></address>
</endpoint>
</send>
</sequence>
conf:/sequencesStackOverFlow/iterOvermpartybranch
<sequence xmlns="http://ws.apache.org/ns/synapse">
<iterate xmlns:ns="http://org.apache.synapse/xsd" xmlns:ds="http://ws.wso2.org/dataservice" expression="//ds:DataCollection/ds:Datalist" id="iterate1" sequential="true">
<target>
<sequence>
<property name="partybranchid" expression="//ds:partybranchid/text()" scope="default" type="STRING"></property>
<property name="clientid" expression="//ds:clientid/text()" scope="default" type="STRING"></property>
<log>
<property name="PARTYID" expression="get-property('partybranchid')"></property>
<property name="CLIENTID" expression="get-property('clientid')"></property>
</log>
<payloadFactory media-type="xml">
<format>
<dat:getselect_addresses xmlns:dat="http://ws.wso2.org/dataservice">
<dat:objectid>$1</dat:objectid>
<dat:clientid>$2</dat:clientid>
</dat:getselect_addresses>
</format>
<args>
<arg expression="get-property('partybranchid')" evaluator="xml"></arg>
<arg expression="get-property('clientid')" evaluator="xml"></arg>
</args>
</payloadFactory>
<log level="full"></log>
<send>
<endpoint>
<address uri="http://127.0.0.1:5555/services/getAddress" format="soap12"></address>
</endpoint>
</send>
</sequence>
</target>
</iterate>
</sequence>
You need to use the aggregate mediator to collect the responses and create one unique message to return to the client. Check my outsequence. In my case I just need to use the transformer mediator to change my payload according to the WSDL.

Resources