Entity Framework not working on IIS? - c#

I have an application running on IIS that i'm testing. Everything was fine until i publish it to the server. Server's ip address is 10.0.0.19 (this is a local application). Connection strings etc. everything is properly configured. Every other query in other pages are working fine but in some pages result sets aren't coming from Entity Framework.
Here is a sample code.
List<CCAP.Data.Orm.CustomerField> fieldList = CustomerFieldProvider.GetCustomerFieldList(projectId);
StringBuilder controlsToRender = new StringBuilder();
foreach (var item in fieldList)
{
HtmlTagBuilder tagParaph = new HtmlTagBuilder("p");
HtmlTagBuilder tagLabel = new HtmlTagBuilder("label");
HtmlTagBuilder tagInput = new HtmlTagBuilder("input");
tagInput.AddAttiribute("type","text");
tagInput.AddAttiribute("style", "width :400px;");
tagInput.AddAttiribute("name", item.FieldName);
tagLabel.AddAttiribute("for",item.FieldName);
tagLabel.SetInnerText(item.FieldHeaderText);
tagParaph.AddChildElement(tagLabel);
tagParaph.AddChildElement(tagInput);
controlsToRender.Append(tagParaph.ToString());
}
return controlsToRender.ToString();
What can be wrong about this situation??

The differences when you publish it to IIS are:
Security context
Configuration file
In your case it is probably the security context. Does your connection string use a trusted connection? Does your app pool identity have access to your SQL server.

Related

LDAP search fails on server, not in Visual Studio

I'm creating a service to search for users in LDAP. This should be fairly straightforward and probably done a thousand times, but I cannot seem to break through properly. I thought I had it, but then I deployed this to IIS and it all fell apart.
The following is setup as environment variables:
ldapController
ldapPort
adminUsername 🡒 Definitely a different user than the error reports
adminPassword
baseDn
And read in through my Startup.Configure method.
EDIT I know they are available to IIS, because I returned them in a REST endpoint.
This is my code:
// Connect to LDAP
LdapConnection conn = new LdapConnection();
conn.Connect(ldapController, ldapPort);
conn.Bind(adminUsername, adminPassword);
// Run search
LdapSearchResults lsc = conn.Search(
baseDn,
LdapConnection.SCOPE_SUB,
lFilter,
new string[] { /* lots of attributes to fetch */ },
false
);
// List out entries
var entries = new List<UserDto>();
while (lsc.hasMore() && entries.Count < 10) {
LdapEntry ent = lsc.next(); // <--- THIS FAILS!
// ...
}
return entries;
As I said, when debugging this in visual studio, it all works fine. When deployed to IIS, the error is;
Login failed for user 'DOMAIN\IIS_SERVER$'
Why? The user specified in adminUsername should be the user used to login (through conn.Bind(adminUsername, adminPassword);), right? So why does it explode stating that the IIS user is the one doing the login?
EDIT I'm using Novell.Directory.Ldap.NETStandard
EDIT The 'user' specified in the error above, is actually NOT a user at all. It is the AD registered name of the computer running IIS... If that makes any difference at all.
UPDATE After consulting with colleagues, I set up a new application pool on IIS, and tried to run the application as a specified user instead of the default passthrough. Exactly the same error message regardless of which user I set.
Try going via Network credentials that allows you to specify domain:
var networkCredential = new NetworkCredential(userName, password, domain);
conn.Bind(networkCredential);
If that does not work, specify auth type basic (not sure that the default is) before the call to bind.
conn.AuthType = AuthType.Basic;

Azure App to Azure Database "Connection Failed" with Entity Framework

I have a C# .Net Web API deployed to an Azure App Service, I also have an Azure SQL Database.
In the API I am using Entity Framework to insert into the database, but I keep getting the error message: "The underlying provider failed on open".
(When running the API locally (in debug mode) connecting to a local database it works fine).
Could this be a permissions/firewall configuration problem with the Azure database, or something else?
I have added my current IP address in the "Azure Set Server Firewall", do I need to add the Azure Web API's IP address to the database firewall settings?
This is my API:
public class ProfileController : ApiController
{
[EnableCors(origins: "*", headers: "*", methods: "*")]
[WebMethod]
[HttpPost]
public HttpResponseMessage PostProfile([FromBody] Profile details)
{
var context = new XXXDBEntities();
var query = from c in context.Users
where c.Email.Equals(details.email, StringComparison.CurrentCultureIgnoreCase)
select c;
var emailFound = query.Count();
if (emailFound != 0)
{
return Request.CreateResponse(HttpStatusCode.OK, "There is already an account associated with this email address");
}
else
{
Guid token = Guid.NewGuid();
Users newRow = new Users();
newRow.Token = token;
newRow.FirstName = details.firstName;
newRow.LastName = details.lastName;
newRow.Email = details.email;
newRow.Password = details.password;
context.Users.Add(newRow);
context.SaveChanges();
return Request.CreateResponse(HttpStatusCode.OK, token);
}
}
This is my connection string:
This is the default format for connection strings in .Net Entity Framework, I have only added username, password and changed the data source and catalog fields. Is this correct?
<add name="XXXDBEntities" connectionString="metadata=res://*/XXXDB.csdl|res://*/XXXDB.ssdl|res://*/XXXDB.msl;provider=System.Data.SqlClient;provider connection string="data source=tcp:XXX.database.windows.net,1433;initial catalog=XXXDB;integrated security=True;User ID=XXXXX;Password=XXXXX;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
I have checked your connection string, it seems to be right. So I think your issue may be caused by the model of the SQL Azure is changed, but your project does not update it. Here is the same issue I reproduced on my side:
I would suggest you update your model.
do I need to add the Azure Web API's IP address to the database firewall settings?
We can set Allow access to Azure services as ON in SQL Azure firewall settings. So that we need not to add Azure web API's address.
You need to remove Integrated Security=True from the connection string since you are specifying a username and password.

Connection to Elasticsearch 5.x is taking to long. NEST 5.0 rc

I am new in Elasticsearch and I have problems with the connection to the elasticsearch server.
I am using Elasticsearch 5.0.1, and I am running my code under .NET 4.5.2.
I am using NEST 5.0 rc lib.
I also installed Kibana and x-pack in my pc.
My code to connect to elasticsearch:
var nodes = new Uri[] { new Uri("http://localhost:9200") };
var pool = new StaticConnectionPool(nodes);
var settings = new ConnectionSettings(pool).DefaultIndex("visitor_index");
var client = ElasticClient(settings);
My Search code:
var result = client.Search<VisitorTest>(s => s.Index("visitor_index")
.Query(q => q.Match(mq => mq.Field(f => f.Name).Query("Visitor 1"))));
Basically the problem that I am having is that each time I create a new ElasticClient it take between 40-80 milliseconds to establish the connection.
I created a UT for this in which I am creating a connection and running the search query twice, and then I am creating a second connection in the same test and run again the search query two times.
The result is that the first query after the connection takes between 40-80 millisecond and the second query with the same connection take 2 milliseconds that is what I expect.
I tried changing the connection string to use a domain (added the domain to my local host file). I also tried removing xpack security so I do not need to authenticate.
xpack.security.enabled: false
But I always get the same result.
A few observations
A single instance of ConnectionSettings should be reused for the lifetime of the application. ConnectionSettings makes heavy use of caching so should be reused.
ElasticClient is thread-safe. A single instance can be safely used for the lifetime of an application
Unless you have a collection of nodes, I would recommend using SingleNodeConnectionPool instead of StaticConnectionPool. The latter has logic to round-robin over nodes which is unneeded for a single node.
The client takes advantage of connection pooling within the .NET framework; you can adjust KeepAlive behaviour on ConnectionSettings with EnableTcpKeepAlive()
If you have a web proxy configured on your machine, you could have a look at disabling automatic proxy detection with .DisableAutomaticProxyDetection() on ConnectionSettings.
I'll add my few coins here.
Had exactly same issue with 40 ms requests. However from Kibana dev tools it was taking 1 ms.
Fixed by tweaking two things:
Ninject part:
kernel.Bind<IEsClientProvider>().To<EsClientProvider>().InSingletonScope().WithConstructorArgument("indexName", "items");
And in client provider:
public ElasticClient GetClient()
{
if (this.client == null)
{
settings = new ConnectionSettings(nodeUri).DefaultIndex(indexName);
this.client = new ElasticClient(settings);
}
return client;
}

Losing item from session intermittently

i am little lost...
we are using sqlserver session sharing and on our production (2 servers) and staging (2 servers), i am loosing one item only from the sessions intermittently. Both, staging and production are load balanced and on same servers but point to different databases.
My local development and the dev site (different server) do not have this issue. These both use the dev database.
Sql server session tables and sprocs are specific to the environment since these are setup in dev, staging or production database.
Code to place items in the session
SessionService.AddItem(SessionKeys.LoggedInUser, user); //this is always available
SessionService.AddItem(SessionKeys.Impersonator, inhouseUser); //this is lost intermittently
public static void AddItem(string key, object value)
{
CheckSessionAvailability();
HttpContext.Current.Session[key] = value;
}
Getting the item from the session:
User inhouseUser = SessionService.GetItem<User>(SessionKeys.Impersonator);
public static T GetItem<T>(string key)
{
object item = null;
CheckSessionAvailability();
item = HttpContext.Current.Session[key];
if ((item != null) && !(item is T))
{
throw new ApplicationException("Cannot convert");
}
return (T)item;
}
Our staging site is load balanced... we disabled node 2 and only made node 1 active. It worked without any issue.
Initially, we had no persistence enabled on the staging or production sites. We enabled cookie-based persistence on the staging site, and while we verified the persistence cookies were coming through in the browser, my page still wasn't consistently working as expected. We switched the load balancer to use persistence based on client IP instead, and then it did appear to be working on staging. Will implement the same on production.

How to have unique entity framework connection strings in each user configuration file

I have a situation when some clients see the server by its local IP and some by global. So that for some of them IP is 10.0.0.4 and for some 94.44.224.132. I use ClickOnce for deployment and Entity Framework to generate the DB mapping. Now ive connection string setting in my user settings section and for each user i store his own one. After that for entity context's construction i do the following:
SomeEntities context = new SomeEntities(new EntityConnection("metadata=res://*/DBModel.csdl|res://*/DBModel.ssdl|res://*/DBModel.msl;provider=System.Data.SqlClient;provider connection string=\"" + Properties.Settings.Default.ServerLocalConnectionString + "\""));
But there are some problems with Open/Close and Command execution after such approach. Is there some right way to store individual connection strings for every client and not overwrite them with deployment(ClickOnce is preferable)?
Found answer here.
EntityConnectionStringBuilder ecb = new EntityConnectionStringBuilder();
if (serverName=="Local")
{
ecb.ProviderConnectionString = Properties.Settings.Default.ServerLocalConnectionString;
}
else
{
ecb.ProviderConnectionString = Properties.Settings.Default.ServerConnectionString;
}
ecb.Metadata = "res://*/";
ecb.Provider = "System.Data.SqlClient";
SomeEntities context = new SomeEntities(new EntityConnection(ecb.ToString());
It seems this works. And now i can deploy the application and leave to the user the decision to which server does he want to connect and leave that configuration after updates, because its written in user's app.config.

Categories