connect to ssas via a web service asmx - c#

hello people i don't know if i am askin properly but i have a big probleme i am new in programming i hope u can help me.
i created an asmx that execute a xmla query on analysis services so evrything is runing perfect when i try it in local but when i deployed on iis in a windows server 2008 r2 and i tested it generated me an error "A connection cannot be made. Ensure that the server is running" can you please guys help me with that i will appreciat it.
"Sorry if my english is bad".
[SoapRpcMethod()]
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public String StartJob(String JobId)
{
string res = "";
string chronomark = (DateTime.Now).ToString("yyy-MM-dd_HHmmss");
String logFile = System.Configuration.ConfigurationManager.AppSettings["log"] + (JobId != null ? JobId : "null") + chronomark + ".log";
try
{
FileStream fs = new FileStream(logFile, FileMode.CreateNew);
StreamWriter swr = new StreamWriter(fs);
try
{
try
{
if (JobId == null) throw new Exception("NO JOB ID GIVEN");
Regex rgx = new Regex("^[0-9A-Z-]{32}$");
if (!rgx.IsMatch(JobId)) throw new Exception("BAD JOB ID");
MatchCollection mcol = rgx.Matches(JobId);
if (mcol.Count != 1) throw new Exception("BAD JOB ID Collection");
String sJobID = mcol[0].Value;
FileInfo fi = new FileInfo(System.Configuration.ConfigurationManager.AppSettings["storage"] + sJobID + ".cube");
if (!fi.Exists)
throw new Exception("NO REGISTRED JOB ID");
FileStream fstr;
try
{
fstr = fi.OpenRead();
}
catch (Exception ex)
{
swr.WriteLine(ex.ToString());
swr.WriteLine(ex.StackTrace);
throw new Exception("NO JOB ID REGISTRED");
}
StreamReader sr = new StreamReader(fstr);
String sTargetServer = sr.ReadLine();
StringBuilder sbrXMLA = new StringBuilder();
sbrXMLA.Append(sr.ReadToEnd());
sr.Close();
fstr.Close();
swr.WriteLine(sbrXMLA.ToString());
swr.WriteLine(sTargetServer);
res = sendXMLARequest(sbrXMLA.ToString(), sTargetServer, swr);
return res;
}
catch (Exception se)
{
swr.WriteLine(se.ToString());
swr.WriteLine(se.StackTrace);
res = "ERROR :" + se.Message.ToString();
return res;
}
}
finally
{
swr.Flush();
fs.Close();
}
}
catch(Exception exp)
{
res = "ERROR : " + exp.Message;
return res;
}
}
[WebMethod]
private String sendXMLARequest(String sXMLARequest, String sTargetServer, StreamWriter logger)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(sXMLARequest);
String Json = JsonConvert.SerializeXmlNode(doc);
Server server = new Server();
server.Connect(#"Provider=OLAP;Data Source=" + sTargetServer);
server.Execute(sXMLARequest);
string con = server.Connected.ToString();
XmlaResultCollection rsCollection = server.Execute(sXMLARequest);
String s = null;
foreach (XmlaResult res in rsCollection)
{
s += res.Value.ToString();
foreach (XmlaMessage message in res.Messages)
{
logger.WriteLine(message.ToString());
if (message is XmlaError)
Json = s + "ERROR : " + message.Description;
else
Json = s + "WARNIN : " + message.Description;
}
}
server.Disconnect();
JavaScriptSerializer js = new JavaScriptSerializer();
return js.Serialize(Json);
}

A possible reason: Lack of access to the IIS process to the SSAS server.
(1) Determine you IIS application pool identity
(2) Give permission to this user in SSAS
Additionally:
(1) How is your web service call authenticated (anonymous / windows authentication / etc) ?
(2) Look at the msmdsrv.log file in SSAS folder
See whether this related SO post helps:
Either the user, 'IIS APPPOOL\App Name', does not have access to the 'SSAS Cube Name' database, or the database does not exist

Related

How to refactor code duplication inside static class?

Below is a section of code that is part of a static class that is giving me trouble refactoring. I've spent a few weeks thinking about ways of approaching this but have been unsuccessful thus far.
Some context - this is part of a TCP Server I'm working on. The TCP Server behaves similar to the websocket specification - when a new client connects, all the management of the client socket is abstracted away, and instead simple callbacks are exposed which can be registered to subscribers.
ie. OnReceived, OnConnect, OnDisconnect, OnSend
This way I can have another class subscribe to the behaviors required from the socket client and keep the responsibilities of managing the socket and business logic separate. Whenever the client socket receives data, it reads the entire data block and then raises the 'OnReceived' callback method, passing in the received data.
The purpose of all of this is to read various requests from a Lua client and perform the appropriate action. Some actions will go to a MySQL Database (via calling stored procedure and passing the request data as arguments to the sproc). There is also the added flexibility of being able to send more than a single dataset in the request, meaning fewer request/responses need to be sent between client and server.
This has been great for many months and has made it very easy to maintain and change the business code without needing to worry about breaking the socket behavior. If I needed to change a stored procedure in a database, it only required updating the database and the Lua client code, as the TCP Server does not care about these implementation details.
However, now there is a new requirement which is to support both MySQL and Redis, and for the TCP Server to be able to direct the request to either of these sources in a flexible way.
The first issue of duplication is the ProtocolResponseSingleData and ProtocolResponseMultiData structs - these structures are almost identical, except for the 'Data' property. I need to be able to return either a single data set, or a collection of data sets. Both of these classes are serialized into a JSON string. This has caused duplication with SendToDBSingleData and SendToDBMultiData methods.
struct ProtocolResponseMultiData
{
public string Action;
public bool Result;
public string Error;
public List<List<object>> Data;
}
struct ProtocolResponseSingleData
{
public string Action;
public bool Result;
public string Error;
public List<object> Data;
}
The second issue is there are 4 methods which are very similar to each other in ways - SendToMySQLDBSingleData, SendToMySQLDBMultiData, SendToRedisDBSingleData, SendToRedisDBMultiData. I just can't seem to figure out how to collapse these down to 1 or 2 methods at most.
The third issue is this class is all static methods - the socket client exposes callbacks, but it is not aware of any particular instance of an object, hence the callbacks need to be declared static. This makes it difficult to apply things like Strategy and Factory patterns to simplify the design.
Is there any hope for me?
public static void OnReceived(object sender, IPCReceivedEventArgs e)
{
try
{
LogToFile(e.data, ((SocketClient)(sender)).LogFile);
Console.WriteLine("Received data from client (" + ((SocketClient)(sender)).Address + ")");
dynamic j = Newtonsoft.Json.JsonConvert.DeserializeObject(e.data);
// Verify the request format is valid
if (j["Action"] != null && j["BulkQuery"] != null && j["Data"] != null && j["Destination"] != null)
{
ProtocolRequest request = new ProtocolRequest
{
Action = j["Action"],
Destination = j["Destination"],
IPAddress = ((SocketClient)(sender)).Address,
LogPath = ((SocketClient)(sender)).LogFile
};
bool isBulkQuery = j["BulkQuery"];
string jsonResp = "";
if (isBulkQuery)
{
ProtocolResponseMultiData resp = SendToDBMultiData(request, ref j);
jsonResp = JsonConvert.SerializeObject(resp);
}
else
{
ProtocolResponseSingleData resp = SendToDBSingleData(request, ref j);
jsonResp = JsonConvert.SerializeObject(resp);
}
((SocketClient)(sender)).Write(jsonResp);
}
else
{
// send malformed request response
string jsonResponse = "{ \"Action\" : " + j["Action"] + ", \"Result\" : false, \"Error\" : \"Malformed Request Received\", \"Data\" : null }";
((SocketClient)(sender)).Write(jsonResponse);
}
}
catch (Exception ex)
{
Console.WriteLine("Exception encountered during OnReceived handler: " + ex.Message);
LogToFile("Exception encountered during OnReceived handler: " + ex.Message, ((SocketClient)(sender)).LogFile);
string jsonResponse = "{ \"Action\" : \"UNKNOWN\", \"Result\" : false, \"Error\" : \"Malformed JSON Request Received\", \"Data\" : null }";
((SocketClient)(sender)).Write(jsonResponse);
}
finally
{
}
}
public static ProtocolResponseSingleData SendToDBSingleData(ProtocolRequest request, ref dynamic j)
{
if (request.Destination == "MYSQL")
{
return SendToMySQLDBSingleData(request, ref j);
}
else if (request.Destination == "REDIS")
{
return SendToRedisDBSingleData(request, ref j);
}
else
{
ProtocolResponseSingleData response = new ProtocolResponseSingleData
{
Action = request.Action,
Error = "Invalid Destination specified - must be either 'REDIS' or 'MYSQL'",
Data = null,
Result = false
};
return response;
}
}
public static ProtocolResponseMultiData SendToDBMultiData(ProtocolRequest request, ref dynamic j)
{
if (request.Destination == "MYSQL")
{
return SendToMySQLDBMultiData(request, ref j);
}
else if (request.Destination == "REDIS")
{
return SendToRedisDBMultiData(request, ref j);
}
else
{
ProtocolResponseMultiData response = new ProtocolResponseMultiData
{
Action = request.Action,
Error = "Invalid Destination specified - must be either 'REDIS' or 'MYSQL'",
Data = null,
Result = false
};
return response;
}
}
private static ProtocolResponseSingleData SendToMySQLDBSingleData(ProtocolRequest request, ref dynamic j)
{
// serialize a new json string for just the data by itself
string jdataString = Newtonsoft.Json.JsonConvert.SerializeObject(j["Data"]);
// now deserialize this string into a list of dictionaries for parsing
Dictionary<string, object> dataDictionary = null;
if (((JToken)j["Data"]).Type == JTokenType.Object)
dataDictionary = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, object>>(jdataString);
else
dataDictionary = new Dictionary<string, object>();
ProtocolResponseSingleData result = new ProtocolResponseSingleData
{
Action = request.Action,
Error = "",
Data = new List<object>(),
Result = false
};
// special scenario - because we cant get the ip address of the game server from DCS, we'll get it from the socket sender object
// and specially insert it as a parameter into the data dictionary
// the other special scenario is the server description request can supply - this can contain harmful html, so we must sanitize the input
if (request.Action == ACTION_GET_SERVERID)
{
dataDictionary.Add("IP", request.IPAddress);
if (dataDictionary.ContainsKey("Description"))
{
try
{
string html = Convert.ToString(dataDictionary["Description"]);
html = System.Web.HttpUtility.HtmlEncode(html);
dataDictionary["Description"] = SanitizeHTML(html);
}
catch (Exception ex)
{
LogToFile("Error sanitizing ServerDescription html string (Action: " + request.Action + ") - " + ex.Message, request.LogPath);
result.Error = "Error sanitizing ServerDescription html string (Action: " + request.Action + ") - " + ex.Message;
return result;
}
}
}
MySql.Data.MySqlClient.MySqlConnection _conn = null;
MySql.Data.MySqlClient.MySqlDataReader rdr = null;
try
{
_conn = new MySql.Data.MySqlClient.MySqlConnection(Config.MySQLDBConnect);
_conn.Open();
MySql.Data.MySqlClient.MySqlCommand cmd = new MySql.Data.MySqlClient.MySqlCommand(request.Action)
{
Connection = _conn,
CommandType = System.Data.CommandType.StoredProcedure
};
foreach (var d in dataDictionary)
{
if (d.Value.GetType() == typeof(Int64) && (Int64)d.Value == LUANULL)
cmd.Parameters.AddWithValue(d.Key, null);
else
cmd.Parameters.AddWithValue(d.Key, d.Value);
}
rdr = cmd.ExecuteReader();
if (rdr.Read())
{
for (int i = 0; i < rdr.FieldCount; i++)
{
result.Data.Add(rdr[i]);
}
}
rdr.Close();
_conn.Close();
result.Result = true;
}
catch (Exception ex)
{
LogToFile("Error executing query against MySQL (Action: " + request.Action + ") - " + ex.Message, request.LogPath);
result.Error = "Error executing query against MySQL (Action: " + request.Action + ") - " + ex.Message;
}
finally
{
if (_conn != null)
if (_conn.State == System.Data.ConnectionState.Open || _conn.State == System.Data.ConnectionState.Connecting)
_conn.Close();
if (rdr != null)
if (!rdr.IsClosed)
rdr.Close();
}
return result;
}
private static ProtocolResponseMultiData SendToMySQLDBMultiData(ProtocolRequest request, ref dynamic j)
{
// serialize a new json string for just the data by itself
string jdataString = Newtonsoft.Json.JsonConvert.SerializeObject(j["Data"]);
// now deserialize this string into a list of dictionaries for parsing
List<Dictionary<string, object>> dataDictionary =
Newtonsoft.Json.JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(jdataString);
ProtocolResponseMultiData result = new ProtocolResponseMultiData
{
Action = request.Action,
Error = "",
Data = new List<List<object>>(),
Result = false
};
MySql.Data.MySqlClient.MySqlConnection _conn = null;
MySql.Data.MySqlClient.MySqlDataReader rdr = null;
try
{
foreach (var d in dataDictionary)
{
_conn = new MySql.Data.MySqlClient.MySqlConnection(Config.MySQLDBConnect);
_conn.Open();
MySql.Data.MySqlClient.MySqlCommand cmd = new MySql.Data.MySqlClient.MySqlCommand(request.Action)
{
Connection = _conn,
CommandType = System.Data.CommandType.StoredProcedure
};
foreach (var kv in d)
{
if (kv.Value.GetType() == typeof(Int64) && (Int64)kv.Value == LUANULL)
cmd.Parameters.AddWithValue(kv.Key, null);
else
cmd.Parameters.AddWithValue(kv.Key, kv.Value);
}
rdr = cmd.ExecuteReader();
if (rdr.Read())
{
List<object> result_set = new List<object>();
for (int i = 0; i < rdr.FieldCount; i++)
{
result_set.Add(rdr[i]);
}
result.Data.Add(result_set);
}
else
{
result.Error += "No Results Returned\n";
}
rdr.Close();
_conn.Close();
}
result.Result = true;
}
catch (Exception ex)
{
LogToFile("Error executing query against MySQL (Action: " + request.Action + ") - " + ex.Message, request.LogPath);
result.Error = "Error executing query against MySQL (Action: " + request.Action + ") - " + ex.Message;
}
finally
{
if (_conn != null)
if (_conn.State == System.Data.ConnectionState.Open || _conn.State == System.Data.ConnectionState.Connecting)
_conn.Close();
if (rdr != null)
if (!rdr.IsClosed)
rdr.Close();
}
return result;
}
private static ProtocolResponseSingleData SendToRedisDBSingleData(ProtocolRequest request, ref dynamic j)
{
// Serialize the JSON Data property into its own JSON String
string jdataString = Newtonsoft.Json.JsonConvert.SerializeObject(j["Data"]);
// now deserialize this string into a list of dictionaries for parsing
Dictionary<string, object> dataDictionary = null;
if (((JToken)j["Data"]).Type == JTokenType.Object)
dataDictionary = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, object>>(jdataString);
else
dataDictionary = new Dictionary<string, object>();
ProtocolResponseSingleData result = new ProtocolResponseSingleData
{
Action = request.Action,
Error = "",
Data = new List<object>(),
Result = false
};
if (!RedisConnection.IsConnected)
{
LogToFile("Connection to Redis Closed - Attempting to reopen...", request.LogPath);
try
{
RedisConnection = ConnectionMultiplexer.Connect(Config.RedisDBConnect);
}
catch (Exception ex)
{
LogToFile("Error connecting to Redis - lost connection (" + ex.Message + ")", request.LogPath);
result.Error = "Error connecting to Redis - lost connection (" + ex.Message + ")";
return result;
}
}
try
{
string serverid = Convert.ToString(dataDictionary["ServerID"]);
string rediskey = Config.RedisActionKeys[request.Action];
if (serverid == null)
{
result.Error = "Error executing query against Redis (Action: " + request.Action + ") - " + "'ServerID' not found in Data request";
return result;
}
if (rediskey == null)
{
result.Error = "Error executing query against Redis - Action: '" + request.Action + "' not found in server configuration - please check action message or server configuration.";
return result;
}
IDatabase db = RedisConnection.GetDatabase();
string k = rediskey + ":" + serverid;
if (!db.StringSet(k, jdataString))
{
result.Error = "Failed to Set Key in Redis (Key: '" + k + "')";
}
else
{
result.Data.Add(1);
result.Result = true;
}
}
catch (Exception ex)
{
LogToFile("Error executing query against Redis (Action: " + request.Action + ") - " + ex.Message, request.LogPath);
result.Error = "Error executing query against Redis (Action: " + request.Action + ") - " + ex.Message;
}
return result;
}
private static ProtocolResponseMultiData SendToRedisDBMultiData(ProtocolRequest request, ref dynamic j)
{
// serialize a new json string for just the data by itself
string jdataString = Newtonsoft.Json.JsonConvert.SerializeObject(j["Data"]);
// now deserialize this string into a list of dictionaries for parsing
List<Dictionary<string, object>> dataDictionary =
Newtonsoft.Json.JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(jdataString);
ProtocolResponseMultiData result = new ProtocolResponseMultiData
{
Action = request.Action,
Error = "",
Data = new List<List<object>>(),
Result = false
};
if (!RedisConnection.IsConnected)
{
LogToFile("Connection to Redis Closed - Attempting to reopen...", request.LogPath);
try
{
RedisConnection = ConnectionMultiplexer.Connect(Config.RedisDBConnect);
}
catch (Exception ex)
{
LogToFile("Error connecting to Redis - lost connection (" + ex.Message + ")", request.LogPath);
result.Error = "Error connecting to Redis - lost connection (" + ex.Message + ")";
return result;
}
}
try
{
int id = 0;
foreach (Dictionary<string, object> x in dataDictionary)
{
id += 1;
string serverid = Convert.ToString(x["ServerID"]);
string rediskey = Config.RedisActionKeys[request.Action];
if (serverid == null)
{
result.Error = "Error executing query against Redis (Action: " + request.Action + ") - " + "'ServerID' not found in Data request";
return result;
}
if (rediskey == null)
{
result.Error = "Error executing query against Redis - Action: '" + request.Action + "' not found in server configuration - please check action message or server configuration.";
return result;
}
IDatabase db = RedisConnection.GetDatabase();
string k = rediskey + ":" + serverid + ":" + id;
string jdatastring = Newtonsoft.Json.JsonConvert.SerializeObject(x);
if (!db.StringSet(k, jdatastring))
{
result.Error = "Failed to Set Key in Redis (Key: '" + k + "')";
result.Result = false;
}
else
{
List<object> res = new List<object>
{
k
};
result.Data.Add(res);
result.Result = true;
}
}
}
catch (Exception ex)
{
LogToFile("Error executing query against Redis (Action: " + request.Action + ") - " + ex.Message, request.LogPath);
result.Error = "Error executing query against Redis (Action: " + request.Action + ") - " + ex.Message;
}
return result;
}

Windows service calling WebGet method returns 400 error

I have a service that runs a c# method to sync a database with active directory at a specified interval. This code has worked in a test environment and now putting it on a different server it is returning the following message:
The server encountered an error processing the request. Please see the
service help page for constructing valid requests to the service.
The help page looks like this:
But the "SyncActiveDirectory" URI is giving me this error:
This is a new server. Maybe i am missing something that needs to be installed or a setting in IIS? Any help would be much appreciated.
EDIT:
Here is the method that called the webget:
private void SyncActiveDirectoryServiceCall()
{
WriteIntoLogFile("Start _schedulerService.SyncActiveDirectoryServiceCall()");
try
{
var reader = new AppSettingsReader();
var serviceurl = reader.GetValue("ServiceUrl", typeof(string));
var client = new RestSharp.RestClient(serviceurl.ToString());
var request = new RestSharp.RestRequest("SyncActiveDirectory", RestSharp.Method.GET);
var response = client.Execute(request);
WriteIntoLogFile(response.Content);
}
catch (WebException ex)
{
using (WebResponse response = ex.Response)
{
HttpWebResponse httpResponse = (HttpWebResponse)response;
WriteIntoLogFile("Error code: " + httpResponse.StatusCode);
using (Stream data = response.GetResponseStream())
using (var reader = new StreamReader(data))
{
string text = reader.ReadToEnd();
WriteIntoLogFile("STREAMED: " + text);
}
}
WriteIntoLogFile("TRY-CATCH: " + ex.ToString());
}
WriteIntoLogFile("End _schedulerService.SyncActiveDirectoryServiceCall()");
}
And here is the method being called:
namespace SyncActiveDirectory
{
public class SyncLocalWithLDAP : ISyncLocalWithLDAP
{
private List<GenericUser> users { get; set; }
private List<GenericUser> roles { get; set; }
[WebGet(UriTemplate = "SyncActiveDirectory")]
public void SyncActiveDirectory()
{
string constr = GetConnectionStringValue("ProteusMMXCustomerDB");
string usr = GetAppsettingValue("ldap_login_username");
string pss = GetAppsettingValue("ldap_login_password");
string filePath = string.Empty;
ActiveDirectoryWrapper wrapper = new ActiveDirectoryWrapper();
if (!Directory.Exists(WebConfigurationManager.AppSettings["LogFolderPath"] + "ServiceLog"))
{
Directory.CreateDirectory(WebConfigurationManager.AppSettings["LogFolderPath"] + "ServiceLog");
}
if (!File.Exists(WebConfigurationManager.AppSettings["LogFolderPath"] + "ServiceLog" + "/" + "SyncLog.txt"))
{
File.Create(WebConfigurationManager.AppSettings["LogFolderPath"] + "ServiceLog" + "/" + "SyncLog.txt").Dispose();
}
filePath = WebConfigurationManager.AppSettings["LogFolderPath"] + "ServiceLog" + #"\" + "SyncLog.txt";
using (StreamWriter w = File.AppendText(filePath))
{
Log("Constr - " + constr + " , u - " + usr + " p - " + pss, w);
try
{
Log("Start sync outer", w);
SyncLocalWithLDAP_Users_Roles(constr, usr, pss, w);
Log("End sync outer", w);
}
catch (Exception ex)
{
Log("Error: " + ex.Message, w);
}
}
}
EDIT:
Pic of htm file added to that directory.
EDIT:
If this helps here is Chrome Developer Tools headers:

"Process cannot access the file because it is being used by another process"

I need to upload a CSV file to an ASP.NET application, on an Azure server. Although it works fine on my local machine, when uploading it to the server the following error is thrown:
"Process cannot access the file
'C:\inetpub\wwwroot\ImportFiles\9_11.csv' because it is being used by
another process"
My code:
string fileName = DateTime.Now.ToString().Replace(':', '_').Replace('/', '_').Replace(' ', '_') + Convert.ToString((new Random()).Next(0, 999) * (new Random()).Next(0, 999));
string path = Server.MapPath("ImportFiles") + "\\" + fileName + "" + FileImport.FileName.Substring(FileImport.FileName.IndexOf('.'));
FileImport.SaveAs(path);
string pathforSeconStream = path;
try
{
Response.Write("<script> alert('In Try Block');</script>");
bool flag = true;
int visiblemessageCount = 0;
int rollNo = 1;
StreamReader ColLine = new StreamReader(path);
string ColInputline = ColLine.ReadLine();
String[] ColsInput = ColInputline.Split(',');
ColLine.Close();
ColLine.Dispose();
string preFix = "", RollNumber = "";
StreamReader sr = new StreamReader(pathforSeconStream);
}
catch(Exception ex)
{
}
The code to generate a unique filename is wrong. Use Path.GetTempFileName.
PS never eat an exceptiion. Please remove catch (Exception ex) {};
Revision
Instead of FileImport.Save(...) just save the request in a MemoryStream and then work on it.

Getting error that file is in use on server but working fine on local system

I am confused whether it is a server issue or coding problem. My strong guess is that it might be a server issue because it is working fine on my local system.
I have upgraded a Asp.net 1.1 website to 4.0. In the application the a file is created by the values that the user enter on the forms. The file is saved in the attachments folder in the application. After the file is created the email is sent to the administrator with attaching the file as an attachment.
On my local system the email is sent just fine. As the application was built in 1.1 CDO is being used to send the emails. When I publish the application on server then attachment is failed and the following error is displayed,
The process cannot access the file 'E:\HostingSpaces\testuser\testapplication.mydomain.com\wwwroot\eTest\Attachment\4orsysil3dulr1iv1thvpade\ef_Comp.exp' because it is being used by another process.
I have given read, write, delete access to the attachments folder. If there is problem in the code then it should also effect the application on the local system too. I have checked all the StreamWriter is closed everywhere it is used.
If this is a server error then what could be the reason?
Edit:
The code is very old written a long time ago and it was working just fine. What I have done is changed the email sending code and specified the SSL and new Port for sending the SMS. Other then that it was not giving error before.
So below is the function which is used to generate the files when the user submit the forms. There are multiple files generated for each form.
private bool GenerateFile()
{
string strSupportDocFile=string.Empty;
string strBespokeFile=string.Empty;
EFormDetails objEFormDetails=new EFormDetails();
DataRow drEForm=objEFormDetails.ResultRow;
string strDirPath = Server.MapPath(#"Attachment/" + Session.SessionID);
try
{
if (!Directory.Exists(strDirPath))
{
Directory.CreateDirectory(strDirPath);
}
StreamWriter ef_File;
StringBuilder strFile=new StringBuilder();
ef_File = new StreamWriter(Server.MapPath(#"Attachment/" + Session.SessionID + #"/" + ConstantsData.EF_COMP_FILENAME));
if(objEFormDetails._EF_COMP != string.Empty)
{
strFile.Append(objEFormDetails._EF_COMP);
ef_File.WriteLine(strFile.ToString());
ef_File.Close();
sbOnFloppyComp=strFile;
}
ef_File = null;
strFile=null;
StringBuilder ef_Cost=new StringBuilder();
strFile=new StringBuilder();
ef_File = new StreamWriter(Server.MapPath(#"Attachment/" + Session.SessionID + #"/" + ConstantsData.EF_COST_FILENAME));
if(objEFormDetails._EF_COST != string.Empty)
{
strFile.Append(objEFormDetails._EF_COST);
ef_File.WriteLine(strFile.ToString());
ef_File.Close();
sbOnFloppyCost=strFile;
}
GetMemberData();
GetOtherDirectorsData();
if(base.IsGuestUser())
{
string strEmailBody;
strEmailBody=GenerateBody();
string strpackage = strEmailBody;
GetPackageDetails(strpackage);
}
return true;
}
catch(Exception ex)
{
lblError.Text=ex.Message.ToString();
return false;
}
}
GetMemberData() function:
private void GetMemberData()
{
EFormDetails objEFormDetails = new EFormDetails();
DataRow drEForm = objEFormDetails.ResultRow;
if (drEForm != null)
{
string strDirPath = Server.MapPath(#"Attachment/" + Session.SessionID);
eFormation.Business.EFDIR efdir = new eFormation.Business.EFDIR();
eFormationResult objResult;
objResult = efdir.LoadEFDIRData(Convert.ToInt64(drEForm[EFORMData.ID_FIELD]), Convert.ToString(drEForm[EFORMData.COMPANYNAME_FIELD]));// + " " + Convert.ToString(drEForm[EFORMData.LIMITED_FIELD])==DBNull.Value ? string.Empty : drEForm[EFORMData.LIMITED_FIELD])));//give efromid adn comapany name
if (!Directory.Exists(strDirPath))
{
Directory.CreateDirectory(strDirPath);
}
StreamWriter swMember;
StringBuilder sb = new StringBuilder();
swMember = new StreamWriter(Server.MapPath(#"Attachment/" + Session.SessionID + #"/" + ConstantsData.EFDIR_MEMBER_FILENAME));
for (int i = 0; i < objResult.ResultData.Tables[0].Rows.Count; i++)
{
sb.Append(objResult.ResultTable.Rows[i][0].ToString());
sb.Append(Environment.NewLine);
}
sbOnFloppyMember = sb;
swMember.WriteLine(sb.ToString());
swMember.Close();
sb = null;
swMember = null;
}
}
GetOtherDirectorsData() function:
private void GetOtherDirectorsData()
{
EFormDetails objEFormDetails = new EFormDetails();
DataRow drEForm = objEFormDetails.ResultRow;
if (drEForm != null)
{
string strDirPath = Server.MapPath(#"Attachment/" + Session.SessionID);
eFormationResult objResult;
eFormation.Business.EFODIR objefodir = new eFormation.Business.EFODIR();
objResult = objefodir.LoadEFODIRData(Convert.ToInt64(drEForm[EFORMData.ID_FIELD]));//change
if (!Directory.Exists(strDirPath))
{
Directory.CreateDirectory(strDirPath);
}
StreamWriter swMember;
StringBuilder sb = new StringBuilder();
swMember = new StreamWriter(Server.MapPath(#"Attachment/" + Session.SessionID + #"/" + ConstantsData.EFODIR_OTHERDIRECTOR_FILENAME));
for (int i = 0; i < objResult.ResultData.Tables[0].Rows.Count; i++)
{
sb.Append(objResult.ResultTable.Rows[i][0].ToString());
sb.Append(Environment.NewLine);
}
sbOnFloppyOtherDirectors = sb;
swMember.WriteLine(sb.ToString());
swMember.Close();
sb = null;
swMember = null;
}
}
GetPackageDetails() function:
private void GetPackageDetails(String strBodyContent)
{
StreamWriter ef_File;
StringBuilder strFile = new StringBuilder();
ef_File = new StreamWriter(Server.MapPath(#"Attachment/" + Session.SessionID + #"/" + ConstantsData.EF_PACKAGE_FILENAME));
ef_File.WriteLine(strBodyContent);
ef_File.Close();
sbOnFloppyComp = strFile;
}
Now all these above mentioned methods are used to create the files.
Now all these files created are added as attachments in the
MailAttachment attachment = new MailAttachment(Server.MapPath(#"Attachment/" + Session.SessionID + #"/" + ConstantsData.EF_COMP_FILENAME));
mEmailMessage.Attachments.Add(attachment);
MailAttachment attachment = new MailAttachment(Server.MapPath(#"Attachment/" + Session.SessionID + #"/" + ConstantsData.EFDIR_MEMBER_FILENAME));
mEmailMessage.Attachments.Add(attachment);
MailAttachment attachment = new MailAttachment(Server.MapPath(#"Attachment/" + Session.SessionID + #"/" + ConstantsData.EF_COST_FILENAME));
mEmailMessage.Attachments.Add(attachment);
See any error?
I have just added these two lines as the email server is now changed to Office 365.
mEmailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpserverport", System.Configuration.ConfigurationSettings.AppSettings["SmtpPort"]);
mEmailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpusessl", true);
Make sure you dispose of your Attachments and your mail message. Otherwise a lock can linger.
mail.Attachments.Dispose()
mail.Dispose()

File gets locked when overwriting

Title explains a small part so let me explain 2 scenarios. Scenario 1 is raising errors, scenario 2 works like a charm.
Scenario 1:
I checkout a document with the method below, when the document is saved to a location where already is a file with that name it gets overwritten, But surprisingly it also locks the file for some reason:
public bool SaveDocument(int bestandsId, string fileName, string path)
{
//Initialize the Sql Query
var sql = "SELECT DATA FROM Documenten WHERE BESTAND_ID = " + bestandsId;
//Initialize SqlConnection
var connection = new SqlConnection(Instellingen.Instance.DmsConnectionString);
//Initialize SqlCommand
var command = new SqlCommand(sql, connection);
try
{
//Open Connection
connection.Open();
//Fill 'data' from command.ExecuteScalar()
var data = (byte[]) command.ExecuteScalar();
//Write 'data' to file.
File.WriteAllBytes(path + #"\" + fileName, data);
//Return true if no exceptions are raised.
return true;
}
catch (Exception ex)
{
//Initialize Dms Exception
var dmsEx = new DmsException(ex);
//Write Dms Exception to Log File.
DmsException.WriteErrorsToLog(dmsEx);
//Return false, because something went wrong...
return false;
}
finally
{
//Close Sql Connection
connection.Close();
}
}
The method runs smoothly. No problems occur. But when I check in the document with the method below, I get this exception:
Scenario 2:
When I use the SaveDocument method to save the document to a location where there isn't a file with the same name, the file is newly created and is ready to be edited or what ever you want to do with it.
Using scenario 2 is working perfect. The document is ready to be checked in again without receiving an error as shown in the picture above.
Request for code by: #CodeCaster
---------------------------------BEGIN EDIT---------------------------------
public static bool InsertDocument(Document document)
{
try
{
//Exception is thrown when Initializing the FileStream
var fileStream = new FileStream(document.Fileinfo.FullName, FileMode.Open, FileAccess.Read);
var binaryReader = new BinaryReader(fileStream);
var totalNumberOfBytes = new FileInfo(document.Fileinfo.FullName).Length;
var data = binaryReader.ReadBytes((Int32) totalNumberOfBytes);
fileStream.Close();
fileStream.Dispose();
binaryReader.Close();
binaryReader.Dispose();
var pdftext = string.Empty;
try
{
if (document.DocumentType == ".pdf")
{
var reader = new PdfReader(document.Fileinfo.FullName);
var text = string.Empty;
for (var page = 1; page <= reader.NumberOfPages; page++)
{
text += PdfTextExtractor.GetTextFromPage(reader, page);
}
reader.Close();
pdftext = text;
}
}
catch (Exception ex)
{
var dmsEx = new DmsException(ex);
DmsException.WriteErrorsToLog(dmsEx);
}
return InsertIntoDatabase(document.BestandsNaam, document.Eigenaar, document.Omschrijving,
document.DatumToevoeg.ToString(), document.DatumIncheck.ToString(),
document.DatumUitcheck.ToString(), document.UitgechecktDoor,
document.DocumentType, data, pdftext, document.Versie, document.Medewerker,
document.DossierNummer, document.PersonalFolderId.ToString(),
document.DossierFolderId, -1, document.DocumentProgres,
document.OriBestandId.ToString(), 0);
}
catch (Exception ex)
{
var dmsEx = new DmsException("Fout bij inlezen voor toevoeging van nieuw document",
"Klasse Document (InsertDocument)", ex);
ExceptionLogger.LogError(dmsEx);
return false;
}
}
---------------------------------END EDIT---------------------------------
My questions:
What is the cause for the file being locked when it gets overwritten?
How can I prevent this from happening?
Is there some sort of function or parameter that I can set so it doesn't get locked?
Using a tool called "Unlocker" I managed to see what program is locking the file, and YES -> DMS.exe is my application.......:
using(var stream = File.Create(newPath)){}
File.WriteAllBytes(newPath, item.File);
With StreamWriter
using (FileStream fs = File.Create(newPath))
{
fs.Write(item.File, 0, item.File.Length);
}
Or:
File.WriteAllBytes(newPath, item.File);
Reference: "The process cannot access the file because it is being used by another process" with Images

Categories

Resources