I am having an asp.net core api project and i am trying to read images that exist in my web site but i am getting 404 not found error.
Code line below that throws an exception when executing GetStreamAsync method:
foreach (var item in imgUrls)
{
// read from remote image drive
using (HttpClient c = new HttpClient())
{
using (Stream s = await c.GetStreamAsync(item))
{
// do something with the stream...
}
}
}
The image url is correct, but when i try to paste it in another tab while the app is running, i don't see the image displayed in my browser. am i missing an asp.net configuration or something that prohibit content files such as images from being displayed through the api response.
Note: the imageUrls we send is FQDN urls, for example the url looks like:
http://localhost:25071/images/test.jpg
looking forward to your help.
This is how i fixed the issue, i didn't enable directory browsing in my asp.net core web api.
So i added my static files (images) folder under wwwroot and added below code in startup.cs to configure/allow directory browsing to images folder and app starts to deliver and show images.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// few standard lines in here.....
// enable directory browsing
app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), #"wwwroot\images")),
RequestPath = new PathString("/images")
});
app.UseDirectoryBrowser(new DirectoryBrowserOptions()
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), #"wwwroot\images")),
RequestPath = new PathString("/images")
});
}
enjoy!
Related
I have a project ASP.NET Core 2.0 MVC running on IIS.
Want to Export some information from data grid to Excel and save it from web page to the desktop of current user.
string fileName = "SN-export-" + DateTime.Now + ".xlsx";
Regex rgx = new Regex("[^a-zA-Z0-9 -]");
fileName = rgx.Replace(fileName, ".");
string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string fileName2 = Path.Combine(path, fileName);
FileInfo excelFile = new FileInfo(fileName2);
excel.SaveAs(excelFile);
This works perfect local at Visual Studio, but not after publishing at IIS.
Using simple path string path = #"C:\WINDOWS\TEMP"; It will save this export file at the server temp folder, but not current web page user.
How to get this?
ASP.NET MVC is framework for a web application. So you have fronted and backend parts. This code will executed on the server side of your application. Even if you use Razor pages, they also generated at the backend. So there are several ways to save data on the computer:
use js to iterate data and save it, but I'm not sure that saving to excel with js is easy;
send desired data to backend, save it to excel and then return to the client.
For a second way you can use next code:
[Route("api/[controller]")]
public class DownloadController : Controller {
//GET api/download/12345abc
[HttpGet("{id}"]
public async Task<IActionResult> Download(YourData data) {
Stream stream = await {{__get_stream_based_on_your_data__}}
if(stream == null)
return NotFound();
return File(stream, "application/octet-stream"); // returns a FileStreamResult
}
}
And because of security reasons you can save data only to downloads directory.
I am having difficulty using a custom index.html and other assets with swashbuckle. Swashbuckle/Swagger do not seem to recognizing or using them at all. I do have app.UseDefaultFiles() and app.UseStaticFiles() set. I am trying to understand what I am doing incorrectly.
I have attempted to set up my configuration somewhat similar to what is defined on the Microsoft article without success. (https://learn.microsoft.com/en-us/aspnet/core/tutorials/web-api-help-pages-using-swagger?tabs=visual-studio)
I am presently using the files from the dist folder referenced in the article (https://github.com/swagger-api/swagger-ui/tree/2.x/dist) along with the custom css file provided.
My index.html file is located under /wwwroot/swagger/ui
The custom css file is located under /wwwroot/swagger/ui/css (as custom.css)
Here is my Startup.cs class.
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddJsonOptions(options =>
{
// Swagger - Format JSON
options.SerializerSettings.Formatting = Formatting.Indented;
});
// Register the Swagger generator, defining one or more Swagger documents
services.AddSwaggerGen(c =>
{
c.DescribeAllEnumsAsStrings();
c.DescribeStringEnumsInCamelCase();
// c.DescribeAllParametersInCamelCase();
c.SwaggerDoc("v1",
new Info
{
Title = "My Web API - v1",
Version = "v1",
Description = "New and improved version. A simple example ASP.NET Core Web API. "
}
);
c.SwaggerDoc("v2",
new Info
{
Title = "My Web API - v2",
Version = "v2",
Description = "New and improved version. A simple example ASP.NET Core Web API. "
}
);
// Set the comments path for the Swagger JSON and UI.
var basePath = AppContext.BaseDirectory;
var xmlPath = Path.Combine(basePath, "ApiTest.xml");
c.IncludeXmlComments(xmlPath);
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
string swaggerUIFilesPath = env.WebRootPath + "\\swagger\\ui";
if (!string.IsNullOrEmpty(swaggerUIFilesPath))
{
app.UseDefaultFiles();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(swaggerUIFilesPath),
RequestPath = new PathString("/api-docs"),
});
}
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger(c =>
{
c.RouteTemplate = "api-docs/{documentName}/swagger.json";
});
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
//c.ShowJsonEditor();
c.RoutePrefix = "api-docs";
c.SwaggerEndpoint("/api-docs/v1/swagger.json", "My Web API - V1 ");
c.SwaggerEndpoint("/api-docs/v2/swagger.json", "My Web API - V2 ");
c.DocumentTitle("My Web API");
});
app.UseMvc();
}
}
My ultimate objective is to be able to use something like the slate style theme available here (https://github.com/omnifone/slate-swagger-ui). For right now, I am just trying to get Swashbuckle/Swagger to use the customized files referenced in the Microsoft documentation before trying to make the other files work.
I really do NOT want to try and convert my assets to embedded resources--since there will many of them. I just want to reference a normal index.html file and be able to use all of its referenced files.
What am I doing wrong?
Relevant Software Versions
.Net Core Version: 2.0.3
Swashbuckle.AspNetCore: 1.2.0
Windows 10 Enterprise Build 1703
Visual Studio 2017 Enterprise 15.5.2
Here is the minimum action I found to be necessary to replace SwashBuckle's index.html in a .NET Core project:
Get a copy of the original index.html from here: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/src/Swashbuckle.AspNetCore.SwaggerUI/index.html
Place that copy in some sub-folder of your project.
The file may have a different name, I chose:
\Resources\Swagger_Custom_index.html
Right-click that file in Solution Explorer, select 'Properties', select 'Configuration Properties' in left pane. Under 'Advanced' in right pane find entry 'Build Action' and set it to 'Embedded resource'. Click Ok.
In Startup.cs add the following line to your app.UseSwaggerUI() call:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//...
app.UseSwaggerUI(c =>
{
c.IndexStream = () => GetType().GetTypeInfo().Assembly.GetManifestResourceStream("Your.Default.Namespace.Resources.Swagger_Custom_index.html");
});
//...
}
The identifier for the file resource in the above GetManifestResourceStream method is composed of:
your default namespace (i.e. 'Your.Default.Namespace')
the sub-path of your resource (i.e. 'Resources')
the filename of your resource (i.e. 'Swagger_Custom_index.html')
All three parts are concatenated using dots (NO slashes or backslashes here).
If you don't use a sub-path but have your resource in root, just omit part 2.
For people who separate ApplicationBuilder config methods on ASP.NET Core:
If the separated method/class is static, it is not possible to call GetType() because an object reference is required.
In that case, switch GetType() to MethodBase.GetCurrentMethod().DeclaringType
c.IndexStream = () => MethodBase.GetCurrentMethod().DeclaringType.Assembly.GetManifestResourceStream("xxx.index.html");
I have developed an application with ASP.NET MVC5. I have used Facebook external authentication in my application.
When I debug this application with the "Locallhost" domain, the Facebook login works well but when I publish the application in the main server,the AuthenticationManager.GetExternalLoginInfo() returns null and it gives me an error like this in the url:
http://xxxxx.com/Account/ExternalLoginCallback?ReturnUrl=%2Fen&error=access_denied#_=_
I have set the "Site URL" as "http://xxxx.com" and "Valid OAuth redirect URIs" as "http://xxxx.com/signin-facebook" in the Facebook development console.
My setting in the Startup.Outh.cs file is:
var FacebookOptions = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationOptions();
FacebookOptions.AppId = ConfigurationManager.AppSettings["Facebook_User_Key"];
FacebookOptions.AppSecret = ConfigurationManager.AppSettings["Facebook_Secret_Key"];
FacebookOptions.Provider = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationProvider()
{
OnAuthenticated = async context =>
{
context.Identity.AddClaim(new System.Security.Claims.Claim("FacebookAccessToken", context.AccessToken));
foreach (var claim in context.User)
{
var claimType = string.Format("urn:facebook:{0}", claim.Key);
string claimValue = claim.Value.ToString();
if (!context.Identity.HasClaim(claimType, claimValue))
context.Identity.AddClaim(new System.Security.Claims.Claim(claimType, claimValue, "XmlSchemaString", "Facebook"));
}
}
};
FacebookOptions.SignInAsAuthenticationType = DefaultAuthenticationTypes.ExternalCookie;
app.UseFacebookAuthentication(FacebookOptions);
I don't know why the external login does not work only in the server with my main domain name. please help me about this problem.
I encountered pretty much the same symptoms you describe:
shortly:
A Facebook authentication worked well on localhost, and after uploading the project to another server (and changing the site URL on Facebook console), authentication did not succeed.
I would recommend you roll back to the MVC template code, and if that works - notice any changes you have made to the middleware code (Startup.Auth.sc).
In particular pay attention to code that interacts with LOCAL configuration, such as Disk I/O and OS permissions for local services.
My particular case:
Starting from the Owin/Katana supported Visual Studio template of a WebAPI project, external login was working perfectly with Facebook, Microsoft and Google OAuth middleware, when testing on localhost.
Later I added come code to Startup.Auth.sc because I needed further authentication activity.
So this was the original code:
public void ConfigureAuth(IAppBuilder app)
{
// see WebAPI template of Visual Studio 2013/2015
...
app.UseFacebookAuthentication(
appId: 99999999,
appSecret: *******);
}
and this was replacement:
public void ConfigureAuth(IAppBuilder app)
{
// see WebAPI template of Visual Studio 2013/2015
...
app.UseFacebookAuthentication(GetFacebookAuth());
}
private FacebookAuthenticationOptions GetFacebookAuth()
{
string picRequest =
String.Format("/me/picture?redirect=false&width={0}&height={0}", ProfileInfoClaimsModel.PIC_SIDE_PX);
var facebookProvider = new FacebookAuthenticationProvider()
{
OnAuthenticated = async (context) =>
{
var client = new FacebookClient(context.AccessToken);
dynamic me = client.Get("/me?fields=id,name,locale");
dynamic mePicture = client.Get(picRequest);
// storing temporary social profile info TO A LOCAL FOLDER
// uploading the local folder to a service WITH A LOCAL CREDENTIAL FILE
...
}
};
var options = new FacebookAuthenticationOptions()
{
AppId = 0123456789,
AppSecret = ******,
Provider = facebookProvider,
};
return options;
}
You may notice that my comments will make the problem obvious - the code points to local resources.
Then I published the project to a virtual server (by Amazon EC2) running Windows Server 2012 with IIS 8.5.
From that moment I kept getting error=access_denied in the redirect from /signin-facebook.
I decided to follow this good old concept, and go back to the original template code. Pretty soon I figured out that I forgot to configure the new server. For instance, the folder the code refers to did not exist and the site had no permission to create it.
Obviously, that solved it.
I have successfully set up using the viewer with the following code:
protected void btnShowPDFS_OnClick(object sender, EventArgs e)
{
// Display all files.
string[] files = Directory.GetFiles(#"D:\Reports\2014\July\", "*.PDF");
var pdfNames = new List<string>();
foreach (string file in files)
{
string fileName = Path.GetFileName(file);
string queryString = "/web/viewer.html?file=" + System.Web.HttpUtility.UrlEncode("../July/" + fileName);
pdfNames.Add(queryString);
}
listView.DataSource = pdfNames;
listView.DataBind();
}
Now, this all works fine if all my PDF's are in a folder within the website (i.e localhost). However, how do i point the view to either a network share, or just another folder on the same machine, but outside of IIS?
A browser's XMLHttpRequest might have a restrictions for local files access (Firefox has more relaxed policy for local file than other browsers).
PDF.js is using XHR; and PDF.js also allows "load" files from a typed array (Uint8Array). You can use the latter in your solution. Notice the Internet Explorer (WebBrowser control) has window.external that can be used to transmit the data from the host application, see http://msdn.microsoft.com/en-us/library/system.windows.forms.webbrowser.objectforscripting(v=vs.110).aspx
Can i make asp application or mvc application that can download data from other server (site) using ftp. I have 2 web sites and i want to download a file from one site to another using ftp.
Yes.
Example copied from How to Download Files with FTP. The example is for a console app, but I think you can figure quite easily how to adapt it to your site's structure.
One thing you might consider is just hosting the file on the site (like normal HTTP) and then download it via WebClient instead of FTP.
using System;
using System.IO;
using System.Net;
using System.Text;
namespace Examples.System.Net
{
public class WebRequestGetExample
{
public static void Main ()
{
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://www.contoso.com/test.htm");
request.Method = WebRequestMethods.Ftp.DownloadFile;
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential ("anonymous","janeDoe#contoso.com");
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
Console.WriteLine(reader.ReadToEnd());
Console.WriteLine("Download Complete, status {0}", response.StatusDescription);
reader.Close();
response.Close();
}
}
}