Problems with an ASMX Web Method that uses File I/O - asp.net

Right now I am working on a stub of a project. In the course of the project I need to be able to from a web front end set a message on a server to and then from an iPhone Query the Server to read the message.
While all the individual peices are working and my request is going through fine I am having trouble using this webmethod
[WebMethod()]
public void setMessage(string message)
{
FileStream file = new FileStream("mymessage.txt", FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter sw = new StreamWriter(file);
sw.Write(message);
sw.Close();
file.Close();
}
When I invoke this via HTTP Post using SOAP from an iPhone app.
I get the following xml in my console when I make the request.
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>Server was unable to process request. ---> Access to the path 'c:\windows\system32\inetsrv\myMessage.txt' is denied.</faultstring>
<detail />
</soap:Fault>
</soap:Body>
</soap:Envelope>
The Server is one configured by my boss, that is currently being used in other capacities as an in house test server for several different projects.
The server is an IIS server I do not know what version, with ASP.NET configured and installed.
The script is located in a different place than the program is trying to write. I assume that the script is being run from that directory and that is why it is trying to write there. Is that the case or am I missing something fundamental?
If there are any alternative suggestions as to how I could go about this I would love to hear them as well, as I am working of a pretty small knowledge base.
Thanks!

Change "filename.txt" to
Server.MapPath("filename.txt")
or specify the full physical path of the file and grant NTFS permissions to the ASP.NET user to be able to access the folder.
Server.MapPath converts virtual paths (e.g. ~/helloworld.aspx) to physical paths (e.g. D:\WebSite\helloworld.aspx).

In addition to storing the file in a folder you have access to (were you unable to read the message?), you need to properly implement "using" blocks:
using (FileStream file = new FileStream("mymessage.txt",
FileMode.OpenOrCreate, FileAccess.Write)) {
using (StreamWriter sw = new StreamWriter(file)) {
sw.Write(message);
}
}
The reason it's writing to c:\windows\system32\inetsrv\ is that this is its default directory. If you want to write to a different directory, then you have tp specify it. Server.MapPath will do that, as has already been pointed out to you.

Related

Silverlight app inside of a asp.net page - The remote server returned and error: NotFound

I've embedded my Silverlight app inside of an asp.net page (of a different project) with the following code:
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
<param name="source" value="SilverlightApplication1.xap"/>
</object>
And it loads up the GUI just fine. However, when the first call to a database is made I receive the error "CommunicationException was unhandled by user code. The remote server returned and error: NotFound."
The Silverlight app works just fine when I run it alone, but when embedded in this page on this other project it doesn't work correctly. I've included both the ProjectView.Web and the Silverlight App itself in the second projects solution, and I changed the output path of the app to the folder where the .aspx file of the page is located.
I've been looking around for awhile and haven't really found anything that helps, it seems that the error is generic and could be anything. I'm thinking it's not able to find the services references because the paths have changed but I'm not entirely sure.
I like Entity Framework for my back end. In the designer it automatically assigns the connection string to the Db on the host computer(development) then when I deploy I use the overload for the container when initialized which is the Connection String to the server Db.
Public Shared Function ModelConnStr() As String
Dim sqlcon As New System.Data.SqlClient.SqlConnectionStringBuilder
sqlcon.DataSource = "tcp:{domain}.com"
sqlcon.InitialCatalog = "db"
sqlcon.UserID = "id"
sqlcon.Password = "pswd"
Dim mdlcon As New System.Data.EntityClient.EntityConnectionStringBuilder
mdlcon.Metadata = "res://*/BMModel.csdl|res://*/BMModel.ssdl|res://*/BMModel.msl"
mdlcon.Provider = "System.Data.SqlClient"
mdlcon.ProviderConnectionString = sqlcon.ConnectionString
Return mdlcon.ConnectionString
End Function
So the same concept applies, use localhost for testing, then before you upload/publish you change the connection string.

How to integrate console app with the existing asp.net mvc 3 app in one solution?

I have a mvc 3 project and I need to populate sql database with data from xml file. So I added the console app project to the solution and wrote the code that will display all needed data on the screen. Now I want to write data into the database. Here is the chunk of code: (fom the console app)
public static void Main()
{
IKernel ninjectKernel = new StandardKernel();
ninjectKernel.Bind<IItemsRepository>().To<ItemsRepository>();
ninjectKernel.Bind<IProductRepository>().To<ProductRepository>();
ninjectKernel.Bind<IShippingRepository>().To<ShippingRepository>();
var itemsRepository = ninjectKernel.Get<IItemsRepository>(); // redirection to datacontext file
var productRepository = ninjectKernel.Get<IProductRepository>();
var shippingRepository = ninjectKernel.Get<IShippingRepository>();
var doc = XDocument.Load(#"C:\div_kid.xml");
var offers = doc.Descendants("offer");
foreach (var offer in offers)
{ // here I use Linq to XML to get all needed data from xml file:
// name, description, price, category, shippingCost, shippingDetails
Product product = productRepository.CreateProduct(name, description, price, category, "Not Specified", "Not Specified");
Shipping shipping = shippingRepository.CreateShipping(shippingCost, shippingDetails);
// here I think I will just create "admin" user and assign its "UserId" to "userId"
Guid? userId = null;
Item item = itemsRepository.CreateItem(product.ProductId, shipping.ShippingId, (Guid) userId, DateTime.Now);
// Resharper highlights this line like unreachable. Why?
Console.WriteLine("name: {0}", offer.Element("name").Value);
}
}
First of all when I run the console app the NullReferenceException occures in MvcProjectName.Designer.cs file in the following line:
public WebStoreDataContext() :
base(global::System.Configuration.ConfigurationManager.ConnectionStrings["WebStoreConnectionString"].ConnectionString, mappingSource)
NullReferenceException: The reference to the object is not pointing to the object instance.
So, I have lots of questions:
1) How to integrate console app code with mvc 3 app code in one solution?
2) I've also found this post on stackoverflow.
But can't I just add reference to MvcProject in references of ConsoleProject? And this way get access to the "mvc repositories" code?
3) Should I use ninject container in console app?
4) Is there any better implementation of loading data from xml file into slq database? I've never had two projects in one solution before, so mabby there are other ways to beautifully handle this situation?
Thanks for Your help in advance!
Edits:
I added app.config file with the connection string:
<add
name="WebStoreConnectionString" connectionString="Data Source=(LocalDB)\v11.0;
AttachDbFilename=|DataDirectory|\WebStore.mdf;Integrated Security=True;Connect Timeout=30"
providerName="System.Data.SqlClient"
/>
Now when I run console app I get the following SqlException when the Linq to SQL ".submitChanges()" method is called:
An attempt to attach an auto-named database for file C:\Users\Aleksey\repos\working_copy\WebStore\LoadDataTool\bin\Debug\WebStore.mdf failed. A database with the same name exists, or specified file cannot be opened, or it is located on UNC share.
Also in the directory LoadDataTool\bin\Debug "WebStore" file with extension "Program Debug Database" appeared.
It's hard to make an accurate assumption on your solution architecture, but from what I'm reading, it doesn't sound like you've separated your Data Access Layer (DAL) from the presentation layer (MVC) - which seems to be why you're trying to referencing it in a console application.
With that assumption, here's how I would answer your questions.
I wouldn't... But if I was going to I was 1) make sure that I have all the required references, 2) validate that the app.config file is setup correctly pointing to the correct database and server.
I would separate your repositories in a different project and use a dependency resolver to inject them into your MVC Application. With that, the console application will only need to reference the DAL assembly - thus not needed all the references in your console app.
If your think that you're going to be pulling out the DAL in the future, then yes. (**See #2 suggestion).
Unless you can't run your solution without the XML file and database created, a better solution is to simply make an administration Controller and Action that allows you to upload your XML file and complete the tasks.
I hope that helps.
Update
For your issue
An attempt to attach an auto-named database for file
Change your connection string so that it looks something like;
Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\WebStore.mdf;
A good source for connection strings is:
http://www.connectionstrings.com/
I guess that you need to define a connection string in the App.config file that is used by your console application (the same way you have it in your web.config):
<connectionStrings>
<add
name="WebStoreConnectionString"
connectionString="YOUR CONNECTION STRING COMES HERE"
providerName="System.Data.SqlClient"
/>
</connectionStrings>

How do I access an ASMX web service using a WebClient?

I am trying to create a method in a class that accesses a WebMethod on a Web Service using WebClient, and am running into problems. Using VS2010 on Windows.
First of all, yes I know I could create a Web Reference to the web service in the class library, of course this is design time binding. However, I need to be able to get to the web service using information only available at run time. There's a business reason for this that I won't go into here, just go with it, please.
This appears to be possible using the WebClient class from the System.Net namespace. And in fact I am able to get to the service in question, but the data I am sending to it doesn't appear to be in a correct format, although for all I can tell it is a properly formatted SOAP message.
The WebException contains the following message: "The remote server returned an error: (415) Unsupported Media Type."
Here's the code:
public string DoingBusiness()
{
WebClient client = new WebClient();
string destUri = "http://localhost/Service/Service.asmx?op=CommunicationsCheck";
StreamReader reader = new StreamReader(#"CommCheck.xml");
string data = String.Format(reader.ReadToEnd(), "The End is Near!");
reader.Close();
string response = client.UploadString(destUri, data);
return response;
}
Leaving off the actual xmlns, which is sensitive, the data read by the StreamReader above looks like:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<CommunicationsCheck xmlns="http://.../">
<communication>{0}</communication>
</CommunicationsCheck>
</soap:Body>
</soap:Envelope>
This looks like a perfectly fine SOAP message. Of course the "{0}" gets filled in with the payload string. If the WebMethod "CommunicationsCheck(string communication) ran successfully it would return:
<?xml version="1.0" encoding="utf-8" ?>
<string xmlns="http://[service url]/">You sent 'The End is Near!'</string>
Which it does if I access the service through a browser, or through a design-time web reference.
So, the question is, what am I doing wrong here that I get the "(415) Unsupported Media Type"
Are there properties on the WebClient that need to be set? Do I perhaps need to provide a Header containing a UserAgent? Or something else?
Darn. I guess I should let someone else answer the question, but answering one's own question is acceptable, if one finds it oneself.
Anyway, some further research on the problem seemed to suggest that one surmise on my part, namely that there might be some Header property I needed to set, was a possible solution. And the research suggested that the property would be "content-type" needed to be set as "text/xml". So I added this line:
client.Headers.Add("content-type", "text/xml");
just before the UploadString method call.
BINGO!
The expected response occurred.
Has anyone ever noticed that answers to perplexing questions sometimes become self-evident once the question is posed, but not before? Interesting phenomenon.

How to save image from remote URL using C# asp.net?

I am working on asp.net C# website in that I getting problem when I try to save image from remote URL.
I have tried with below c# code ...
// C# code
string remoteImageUrl= "http://www.bitpixels.com/getthumbnail?code=83306&url=http://live.indiatimes.com/default.cms?timesnow=1&size=200";
string strRealname = Path.GetFileName(remoteImageUrl);
string exts=Path.GetExtension(remoteImageUrl);
WebClient webClient = new WebClient();
webClient.DownloadFile(remoteImageUrl,Server.MapPath("~/upload/")+strRealname + exts);
When I fetch image from above remoteImageUrl then I getting error "An exception occurred during a WebClient request."
How can I fetch and save remote url image and store it my website upload directory.
or any other way to get remote url image.
I solved that problem The exception comes due to the extension..
When I getting extension of the remoteImageUrl Path.
string exts = Path.GetExtension(remoteImageUrl);
string strRealname = Path.GetFileName(remoteImageUrl);
It returns ".cms" so exception throws at that point,
I avoid the ".cms" extension from the remoteImageURL and then call
WebClient webClient = new WebClient();
webClient.DownloadFile(remoteImageUrl,Server.MapPath("~/upload/")+strRealname + exts);
It works fine.
Yout code is just fine. Make sure your application pool identity, has access to "upload" folder with write access.
And if you are using a proxy server you should also specify this in web.config file.
<system.net>
<defaultProxy enabled="true" useDefaultCredentials="true"></defaultProxy>
</system.net>
Are you running under anything less than full trust? If so, you can't make arbitrary web requests either.

ASMX Service and Lack of Crossdomain.xml file

I have an issue with an asmx service I am trying to access. No crossdomain file. I read there is a way around this using HTTPService instead of a webservice. Still cannot load the wsdl. See code below. Any help would be greatly appreciated:
var dataService:HTTPService = new HTTPService();
dataService.url =
"http://flexmappers.com/proxy.php?url=http://www.server.net/carbon.asmx";
dataService.method = "POST";
dataService.addEventListener("result", onCarbonCalcResult);
dataService.addEventListener("fault", onCarbonCalcFault);
//dataService.resultFormat = "xml"
var params:Object = new Object();
params["call"] = "getCarbon";
params.area = carbonarea;
params.geojson = geojson;
dataService.send(params);
No crossdomain file. I read there is a
way around this using HTTPService
instead of a webservice
It sounds like you were misinformed.
In browser based applications, neither HTTPService, WebService, and RemoteObject tags are not allowed to access content on a remote server unless a crossdomain.xml file exists allowing such access. They can all access content on the same domain as the SWF without a crossdomain.xml file in place.
To get around this, you can use an HTTP Proxy on the same server that serves your SWF. You could also use an AIR app which does not run in a browser, and therefore exists in a different security sandbox.
You can create your own proxy with BlazeDS or Apache HTTP.

Resources