Consuming a click-once application from an MVC controller/action - asp.net-mvc

I am using an MVC controller/action located in /myServer/myArea/MyClickOnce/Open that returns a FileResult
public class MyClickOnceController : Controller
{
public FileResult Open()
{
FilePathResult file = new FilePathResult("/Provisioning/4843EA3F-9138-4A0D-9D33-BF4CDDEB7C7E/MyClickOnce.application", "application/x-ms-application");
return file;
}
}
this works fine for the initial loading, but then click-once makes a subsequent request to:
/myServer/myArea/MyClickOnce/9.0.0.132/MyClickOnce.exe.manifest
This path doesn't actually exist because the physical path for the click once is in:
/Provisioning/4843EA3F-9138-4A0D-9D33-BF4CDDEB7C7E/*
so it exists here:
/Provisioning/4843EA3F-9138-4A0D-9D33-BF4CDDEB7C7E/9.0.0.132/MyClickOnce.exe.manifest
Should I be using routing to redirect all these subsequent requests? Is there a better approach to consume a click-once application from and MVC controller/action?

If you use a RedirectResult, the subsequent requests to the ClickOnce manifest and other files get routed to the correct directory.
public ActionResult Open()
{
string path = "/Provisioning/4843EA3F-9138-4A0D-9D33-BF4CDDEB7C7E/MyClickOnce.application";
return new RedirectResult(path);
}

Related

.Net MVC returning a File

I'm working a Controller that will generate/retrieve files. These will optionally set headers.
public IActionResult SampleFileReport()
{
I see the return type is IActionResult (a data contract). I see inside the function I can still set
response.ContentType
Is there a preferred pattern for how to set ContentType in a controller?
I'm thinking it should be part of the DataContract and setting response.contentype is an anti-pattern, however I see examples such as this that utilize it. Returning a file to View/Download in ASP.NET MVC
All you need to do is return File:
public IActionResult SampleFileReport()
{
// do stuff
return File(bytes, mimetype, filename);
}
File also has overloads that accept Stream and string (path and filename to a file on the filesystem) in addition to byte[]. The mimetype is your content type, e.g. application/pdf, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet (Excel), etc. The final filename param is optional. If it's provided, a Content-Disposition: attachment header is sent with the response, which prompts the browser to pop a download dialog. Otherwise, the default Content-Disposition: inline is used, and the browser will try to load the returned file directly the browser tab/window, assuming the mime-type is supported for native rendering the browser. If not, then you'll get a download dialog, regardless.
If we are talking about MVC (not .NET Core) then you can change IActionResult to FileContentResult
public FileContentResult SampleFileReport()
{
byte[] fileBytes = GetFileBytes();
return File(fileBytes, MediaTypeNames.Application.Octet, "fileName");
}
Just checked this class still exists. FileContentResult .NET Core

Performance ramifications of serving FilePath rather than View

What are the performance ramifications if any of serving a FilePathResult rather than a view (If we have created server cached copies of a website using a headless browser)
public class HomeController : Controller
{
public ActionResult Index()
{
var url = Request.RawUrl.Replace("/", "_");
var path = System.Configuration.ConfigurationManager.AppSettings["PreloadPath"] + "\\" + url + ".html";
if (System.IO.File.Exists(path))
{
return new FilePathResult(path, "text/html");
}
else
{
return View("Index");
}
}
}
We are having to access the AppSettings every request now, use the File System to check if a file exists, and then serve that html file.
What costs are there compared with just
return View("Index");
Will the file access have any cost on the server? Or am I talking nonsense, and IIS would have to perform some similar action?
Note: Please suggest any other tags if I should add them
Looking at the FilePathResult's source code you can see that in the end it goes down to WriteStreamAsText of HttpResponse. It's obvious that there is no magic call to IIS for example to handle the file directly without any .Net code taking place.
Having said that I still expect this to be somewhat faster than running a view, which possibly needs interpretation and execution.

C # MVC view files only for logged in users

how can I set about c # MVC viewing files with absolute path (eg. www.mysite.it/namefile.pdf) only for authenticated users ? for authentication use the method FormsAuthentication.Authenticate(). thanks for the support.
I think that the more properly way to do that is:
www.mysite.it/f={filename}
And in your controller you use the [Authorize] to check if user is authenticated. If the user is authenticated you allow him to view, or download, the file.
The following code can help you to understand:
//Ensure that the user is authenticated
[Authorize]
public class HomeController : Controller
{
string DefaultFileFolder = "C:/Files";
public ActionResult Index(string f)
{
//File request
if (!String.IsNullOrWhiteSpace(f))
{
var filePath = System.IO.Path.Combine(DefaultFileFolder, f);
var mimeType = "text/plain";
return File(filePath, mimeType);
}
return View();
}
}
As far as I know the only way to do this is to route requests for static content through ASP.NET. Normally you don't do this as IIS by itself is far more efficient at serving these types of resources.
From this excellent article, you can force static content requests to go through ASP.NET by:
On IIS 7 this is done either by setting
runAllManagedModulesForAllRequests=”true” or removing the
"managedHandler" preCondition for the UrlRoutingModule.
Depending on your needs, you may wish to do something more in line with what Richard suggested. Something like this perhaps?

RediretAction in MVC causes "The Web server is configured to not list the contents of this directory"

I have a contentController like this :
public class ContentController : Controller
{
public ActionResult Index()
{
var model = obj.GetContentlist();
return View(model);
}
[HttpPost]
public ActionResult Create(Content content)
{
obj.AddNewContent(content);
obj.Save();
return RedirectToAction("Index","content");
}
}
That as you can see contains create action .But in the last line ,when it is going to be executed RedirectToAction("Index","content"); i got this error :
HTTP Error 403.14 - Forbidden
The Web server is configured to not list the contents of this directory.
Most likely causes:
A default document is not configured for the requested URL, and directory browsing is not enabled on the server.
The default MVC template includes a "Content" folder. Since you're redirecting to content/index and index is most likely the default action, you actually get redirected to /content -- which is the content directory rather than your controller. If I were you I would choose another name for your controller to avoid the conflict.

Allow direct access to some file/content in Asp.Net MVC

In my Asp.Net MVC application, I am using a customized template of twitter bootstrap.
I have placed this template folder named "b3-detail-admin" on root of my mvc application.
Using Browser's address bar, when I am trying to access one file directly from this folder like so:
http://my-pc/MyWebAppMvc/b3-detail-admin/font/fontawesome-webfont.woff
I am getting following error:
HTTP Error 404.3 - Not Found
The page you are requesting cannot be served because of the extension configuration. If the page is a script, add a handler. If the file should be downloaded, add a MIME map.
What should I do to have direct access to all files/folders under "b3-detail-admin" folder?
In mvc you can only get access to the routes defined in RouteConfig.
You can add a ActionResult which returns the document like so:
public ActionResult GetPdf()
{
string file = Server.MapPath("~/folder/file.pdf");
return File(file, "application/pdf", "file.pdf");
}
You then can make it dynamic to get all sorts of files:
public ActionResult GetFile(string url, string mime)
{
string file = Server.MapPath(url);
string filename = url.Split(new char[]{'/'})[url.Split(new char[]{'/'}).Count()];
return File(file, "mime", filename);
}

Resources