Clicking Open Word Document tries to reconnect to Controller action while downloading - asp.net-mvc-3

I have a requirement to download a file from the server, but open inline if possible. I'm currently doing;
Response.AddHeader("Content-Disposition", string.Format("inline; filename={0}", documentFileName));
result = new FileStreamResult(new FileStream(documentFilePath, FileMode.Open), "application/msword");
I've put application/msword in there right now, because that's what I'm having a problem with. When I click Open on the word document, it's as if the document makes multiple calls back to the action, but there is no session and no database so it crashes. When the user is running this, they see a long hang, the "Downloading" dialog finally appears in word and they have to cancel it. The document is there and is valid but this is not desirable.
Pdfs, pngs etc. download fine. Can anybody explain this behavior, and give me some hints as to how I fix it?
Update:
The action basically looks like;
[HttpPost]
public FileResult View(int id, int source)
{
var document = GetDocumentFromDatabase(id, source);
documentFilePath = Path.Combine( documentsDirectory, document.Name);
documentName = document.Name;
Response.AddHeader("Content-Disposition", string.Format("inline; filename={0}", documentFileName));
result = new FileStreamResult(new FileStream(documentFilePath, FileMode.Open), "application/msword");
return result;
}
I've trimmed it down, as I can't share the specifics, but the full idea is there.
Answer:
I have a lookup of available content-types, in there I have defined whether the file is inline or attachment, and when I detect a word document, I set it to attachment. No more error. PDF opens in the browser still because I set it to inline.

I use:
public ActionResult GetAttachment(int id)
{
var attachment = _repository.GetAttachByID(id);
if (attachment != null)
{
Response.AppendHeader("Content-Disposition",string.Format("inline; filename={0}",attachment.FileName));
return File(attachment.File, attachment.MimeType, attachment.FileName);
}
else
{
return null;
}
}
Regards

Related

Cannot make XBAP cookies work

I am trying to make a XBAP application communicating with a webservice with login.
But I want the user to skip the login step if they already logged in the last seven days.
I got it to work using html/aspx.
But it fails continuously with XBAP.
While debugging, the application is given full trust.
This is the code I have so far to write the cookie:
protected static void WriteToCookie(
string pName,
Dictionary<string, string> pData,
int pExiresInDays)
{
// Set the cookie value.
string data = "";
foreach (string key in pData.Keys)
{
data += String.Format("{0}={1};", key, pData[key]);
}
string expires = "expires=" + DateTime.Now.AddDays(pExiresInDays).ToUniversalTime().ToString("r");
data += expires;
try
{
Application.SetCookie(new Uri(pName), data);
}
catch (Exception ex)
{
}
}
And this is what I have to read the cookie:
protected static Dictionary<string, string> ReadFromCookie(
string pName)
{
Dictionary<string, string> data = new Dictionary<string, string>();
try
{
string myCookie = Application.GetCookie(new Uri(pName));
// Returns the cookie information.
if (String.IsNullOrEmpty(myCookie) == false)
{
string[] splitted = myCookie.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
string[] sub;
foreach(string split in splitted)
{
sub = split.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
if (sub[0] == "expires")
{
continue;
}
data.Add(sub[0], sub[1]);
}
}
}
catch(Exception ex)
{
}
return data;
}
The pName is set with:
string uri = "http://MyWebSiteName.com";
When the user authenticate the first time, I call the WriteToCookie function and set it with 7 days to expire.
It looks like everything is fine as I get no exception of error messages. (I have a break point in the catch)
After that, I close the session and start it again.
The first thing I do is a ReadFromCookie.
Then I get an exception with the following message: No more data is available
So my application is sending the user automatically back to the login screen.
I also tried to do a ReadFromCookie right after the WriteToCookie in the same session, and I get the same error.
Application.SetCookie(new Uri("http://MyWebSiteName.com/WpfBrowserApplication1.xbap"), "Hellllo");
string myCookie2 = Application.GetCookie(new Uri("http://MyWebSiteName.com/WpfBrowserApplication1.xbap"));
It seems to me that the cookie is not even written in the first place.
So I am guessing I am doing something wrong.
Maybe the uri I am using is wrong. Is there a specific format needed for it?
Just like you need a very specific format for the expire date.
I have been searching quite a lot of internet for a good sample/tutorial about using cookies with XBAP, and I could not find anything really well documented or tested.
A lot of people say that it works, but no real sample to try.
A lot of people also handle the authentication in html, then go to the XBAP after successfully reading/writing the cookies.
I would prefer a full XBAP solution if possible.
To answer some questions before they are asked, here are the project settings:
Debug:
Command line arguments: -debug -debugSecurityZoneURL http://MyWebSiteName.com "C:\Work\MyWebSiteName\MyWebSiteNameXBAP\bin\Debug\MyWebSiteNameXBAP.xbap"
Security:
Enable ClickOnce security settings (Checked)
This is a full trust application (selected)
I also created a certificate, and added it the 3 stores like explained in "publisher cannot be verified" message displayed
So I do not have the warning popup anymore. I just wanted to make sure that it was not a permission issue.
Finally found the answer to this problem.
Thanks for this CodeProject I was finally able to write/read cookies from the XBAP code.
As I had guessed, the URI needs to be very specific and you cannot pass everything you want in it.
What did the trick was using: BrowserInteropHelper.Source
In the end the read/write code looks like:
Application.SetCookie(BrowserInteropHelper.Source, data);
string myCookie = Application.GetCookie(BrowserInteropHelper.Source);
It looks like you cannot use ';' to separate your own data.
If you do so, you will only get the first entry in your data.
Use a different separator (ex: ':') and then you can get everything back
The data look like this:
n=something:k=somethingElse;expires=Tue, 12 May 2015 14:18:56 GMT ;
The only thing I do not get back from Application.GetCookie is the expire date.
Not sure if it is normal or not. Maybe it is flushed out automatically for some reason. If someone knows why, I would appreciate a comment to enlighten me.
At least now I can read/write data to the cookie in XBAP. Yeah!

windows phone c# check for valid url and replace foreach item in list

I am getting a list of objects in Windows Phone, and show them in a listbox with databinding.
some image urls are not valid, so after every object is added in the list, i run the following code to check and replace, if not valid
private void CheckLinkUrl(Person p)
{
Uri filePath = new Uri(p.img_url);
string correct = p.img_url;
HttpWebRequest fileRequest = HttpWebRequest.CreateHttp(filePath);
fileRequest.Method = "HEAD";
fileRequest.BeginGetResponse(result =>
{
HttpWebRequest resultInfo = (HttpWebRequest)result.AsyncState;
HttpWebResponse response;
try
{
response = (HttpWebResponse)resultInfo.EndGetResponse(result);
}
catch (Exception e)
{
p.img_url = "http://somethingelse.com/image.jpg";
}
}, fileRequest);
}
the problem is that it is very slow, it takes sometimes 2 minutes+ to load every image (although the UI remains responsive, and everything else is displayed immediately in the listbox, apart from the images)
am I doing something wrong? can i get it to run faster?
EDIT:
I tried using the imagefailed event and replace the link, no improvement at the speed of loading the pics
What I have done to avoid this problem in my application is, I have loaded the items with a default Image, The image source is binded to a property in my result item of type ImageSource. By default it returns the default image. After processing or download completion the imagesource value changes to the new Image triggering the NotifyPropertyChanged event and hence it is automatically reflected on the UI. I hope it helps you.

Returning an MVC FileContentResult to download .pdf file from

Hi I've search around for this quite a bit but I didn't find a situation that really resembled mine..hope I didn't miss a duplicate somewhere
The Goal: Return a file from a UNC share to the client as a download/open option.
Info: The share is located on a different server than the one hosting the web site. When a corresponding folder name on the menu is clicked, I am able to successfully read from the share (I return the files as a JSON result) and in Jquery I then append list items for each file found in the folder and make the list item ID's the filename. This works great.
When these appended list items are clicked on I pass their ID's (which are the filename, like "thefile.pdf") to the following controller which returns a FileContentResult.
files[0].ToString() below is similar to "\server\folder\"
public ActionResult OpenTheFile(string id)
{
List<string> files = new List<string>();
files.AddRange(Directory.GetFiles(LNFiles.ThePath, id, SearchOption.AllDirectories));
Response.AppendHeader("Content-Disposition", "attachment; filename=" + id + ";");
return File(files[0].ToString(), System.Net.Mime.MediaTypeNames.Application.Pdf, id);
}
And yes the obligatory "it works on my local machine". When deployed to the IIS 7.5 server and I click on the list item I get this YSOD error:
The handle is invalid. (Exception from
HRESULT: 0x80070006 (E_HANDLE))
I'm impersonating a user with rights to the file share...I'm at a loss, i was thinking something with encoding or screwed up rights? I've tried using a virtual dir instead but alas same issue.
In my case
changing this:
public ActionResult Download(int id)
{
var item = ItemRepo.GetItemById(id);
string path = Path.Combine(Server.MapPath("~/App_Data/Items"), item.Path);
return File(path, "application/octetstream", item.Path);
}
to this:
public ActionResult Download(int id)
{
var item = ItemRepo.GetItemById(id);
string path = Path.Combine(Server.MapPath("~/App_Data/Items"), item.Path);
return File(new FileStream(path, FileMode.Open), "application/octetstream", item.Path);
}
has worked. I am putting this here just in case anyone needs.
Check out this for a workaround
You may want to try a packet capture to see if you are receiving the same issue as documented here:
http://forums.asp.net/t/1473379.aspx/1
For your unc path - are you directly referencing \servername\share or are you using a network mapped drive letter?
God Bless you : ProgRockCode.
and since that involved an ActionResult, I wrote a custom ActionResult that used the "WriteFile" method.
public override void ExecuteResult(ControllerContext context)
{
context.HttpContext.Response.WriteFile(FilePath, true);
context.HttpContext.Response.End();
}

MVC 3 ContentResult binary file with firefox strange issue

I've got an MVC 3 app that allows users to upload files with some data entry stuff. I've set up a controller that fetches those documents and buffers them out to the user like so
[OutputCache(Duration = 1200, VaryByParam = "id")]
public ContentResult GetNarrative(int id)
{
Response.Clear();
Response.BufferOutput = true;
Response.ContentType = "application/octet-stream";
var narrative = attachRepo.GetNarrative(id);
if (narrative == null || narrative.Narrative == null)
return null;
Response.AddHeader("Content-Disposition",
string.Format("attachment;filename={0}",
Server.UrlEncode(narrative.Filename)));
Response.OutputStream.Write(narrative.Narrative.ToArray(),
0, narrative.Narrative.ToArray().Length);
Response.OutputStream.Flush();
return Content("");
}
This works fine and well, the interesting thing is that when I have the output cache line, my firefox download dialog looks like this
However when I comment out the output cache line it looks like the expected dialog
This isn't really a blocking issue, as it works just fine in IE and Chrome just downloads by default, but I am curious why this would be happening and if anyone has experienced this and worked around it.
Thanks!
I've found that firefox ignores the filename in the Attachment. It tends to use he URL to set the filename.
Try putting at the end of the URL ?filename.docx
And see if it fixes things.

Opening Word Document from IE

I'm opening a word document through IE on a local network, it opens up fine but if a document is password protected then it should prompt for the password which it doesn't.
Is there something that I should be doing to get the password prompt?
The way I'm opening the document is by a link on a web page e.g.
Document
I've got what I want working using the following javascript/jQuery.
jQuery is not required, I used it as I already have it as part of the project.
$('a.openDoc').live('click',function(){
var file = $(this).attr('href');
// This is what does the work.
try
{
try
{
// get Word Active-X Object if Word is open.
var word = GetObject('',"Word.Application");
}
catch(e)
{
// create new Word Active-X Object.
var word = new ActiveXObject("Word.Application");
}
word.Visible = true; // Make sure Word is visible.
word.Documents.Open(file); // Open the file you want.
}
catch(e)
{
alert(e.description);
}
// End work.
return false;
});
In case you are ok with having the document open in Word itself (and not in IE), maybe this will point you in the right direction:
http://www.velocityreviews.com/forums/t109523-open-word-doc-in-word-not-in-browser.html

Resources