ServiceStack SelfHosted Site Default page - servicestack

I have tried all the Razor self-hosted and the servicestack templates and in those projects it is possible to serve static html and cshtml if you have the razorFormat installed. I don't know what I am doing wrong and I have just copied code into new solutions and I cannot get html responses to work. I can get the metadata page always and the services work. I am not able to add default.htm and get it to work.
If I type in http://localhost:1337 I should get directed to the default page. Maybe I am missing something but I don't know what it is. If someone can give me a hand I would appreciate it greatly!
Here is my default.htm
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title></title>
</head>
<body>
SOMETEXT
</body>
</html>
Here is my Program
class Program
{
[Route("/hello")]
[Route("/hello/{Name}")]
public class Hello
{
public string Name { get; set; }
}
public class HelloResponse
{
public string Result { get; set; }
}
public class HelloService : Service
{
public object Any(Hello request)
{
return new HelloResponse { Result = "Hello, " + request.Name };
}
}
public class AppHost : AppHostHttpListenerBase {
public AppHost() : base("StarterTemplate HttpListener", typeof(HelloService).Assembly) {
}
public override void Configure(Funq.Container container) {
container.Register(new HelloService());
}
}
static void Main(string[] args)
{
var listeningOn = args.Length == 0 ? "http://*:1337/" : args[0];
var appHost = new AppHost();
appHost.Init();
appHost.Start(listeningOn);
Console.WriteLine("AppHost Created at {0}, listening on {1}", DateTime.Now, listeningOn);
Console.ReadKey();
}
}
Edit:
I should have added what the response I am getting is.
Handler for Request not found:
Request.HttpMethod: GET
Request.HttpMethod: GET
Request.PathInfo: /default.htm
Request.QueryString:
Request.RawUrl: /default.htm
One more thing that I tried was to put a request filter in at AppHostHttpListenerBase.Configure. I do not ever even hit that in my project but I do in the template projects.
EDIT:
I found out that the problem is that my Default.html and app.Config files are not getting moved to the bin/Debug directory. Has anyone experienced that problem?

Here is a good blog post on serving Razor pages for a self-hosted/console app. I don't think you need an app.config or web.config file, though I could be wrong.
The two things I think that you're missing:
1) Add Plugins.Add(new RazorFormat()) to the Configure method in your AppHost
2) Change 'Copy to Output Directory' value to 'Copy if newer' for your Razor files (this is within the Properties settings of the file). Also, change your default.htm file to default.cshtml.

For xamarin in OS X 'Copy to Output Directory' will definitely be a pain in the ass, because you should select this option on each file, and sometimes twice. So another option is create symbolic link
ln -s /path_to_project/assets /path_to_project/bin/Debug/assets
ln -s /path_to_project/Views /path_to_project/bin/Debug/Views
It's very useful for hundreds of files in assets and just a little bit easier for Views folder.
The same can be done on Linux hosting to hide selfhost.exe and *.dll in bin folder

Related

How to insert code in the static files like .html, .htm, .asp on IIS for non-asp project

I want to add a script on my IIS Server.
So that it will be applied on all the websites that are upload will have that script in their request response.
Anyone who knows how to do it?
I had implemented the IHttpModule and IHttpHandler, it works fine for the asp.net projects.
but if the website contains only html, css, and js files in the folder, this solution doesn't work.
Here the HttpModule and HttpHandler
public class MyCustomHttpModuleClass : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.PostRequestHandlerExecute += OnPostRequestHandlerExecute;
}
public void OnPostRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication application = sender as HttpApplication;
HttpContext context = application.Context;
context.Response.Write("<h1>alert('HELLO')</h1>");
}
}
public class MyHandler : IHttpHandler
{
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
context.Response.Write("<h1>alert('HELLO')</h1>");
}
}
I'm not sure if you have learnt how to add Custom Module and Handler in IIS. After tested your module and handler with static website, it works fine.
I will just give you a sample of adding them to IIS.
1.Create a project "class library .netframework". I name the project"ClassLibrary1"
2.Add class "MyCustomHttpModuleClass" and "MyHandler" to the project
3.Build this solution and find "ClassLibrary1.dll" in the "project/bin/debug" folder.
4.Copy "ClassLibrary1.dll" to the website root "BIN" folder.
5.Add managed module and handler by choose your dll.(should in the list after you copied)Just mention that your custom handler only work on the file extension you set up.
Now they work.

razorpage constructor injection does not work, while view injection does work

This is my code:
*.cshtml
#page
#model WebSite.Feature.Debugging.Areas.Debug.Pages.ListFeaturesModel
#{
}
<h1>Currently loaded features:</h1>
#foreach (var item in Model.Features)
{
<li>#item.Name</li>
}
Codebehind:
public class ListFeaturesModel : PageModel
{
public IEnumerable<IFeature> Features { get; }
public ListFeaturesModel(IEnumerable<IFeature> features)
{
Features = features;
}
public void OnGet()
{
}
}
The exception i get when navigating to the page:
Oddly enough if i use #inject in the cshtml it works just fine. Has anyone run into this issue before?
The razorpage is placed inside a dynamically loaded Razor class library.
Repo to reproduce: https://github.com/taori/Sandbox.git
Build whole solution, run web application, navigate to MyFeature/Page1
The underlying issue was that i was loading plugins through Assembly.LoadFrom, instead of AssemblyLoadContext.Default.FromPath - While Load from works fine most of the time it struggles in netcore scenarios where dependencies are an issue.
Unfortunately the exception i got wasn't helpful so further digging was necessary.

SwaggerRequestExample attribute does not work in ASP.NET MVC 5 (.NET Framework 4.5.2)

I am toying with Swashbuckle.Examples package (3.10.0) in an ASP.NET MVC project. However, I cannot make request examples appear within the UI.
Configuration (SwaggerConfig.cs)
public static void Register()
{
var thisAssembly = typeof(SwaggerConfig).Assembly;
GlobalConfiguration.Configuration
.EnableSwagger(c => {
c.SingleApiVersion("v1", "TestApp.Web");
c.IncludeXmlComments(string.Format(#"{0}\bin\TestApp.Web.xml", System.AppDomain.CurrentDomain.BaseDirectory));
c.OperationFilter<ExamplesOperationFilter>();
c.OperationFilter<DescriptionOperationFilter>();
c.OperationFilter<AppendAuthorizeToSummaryOperationFilter>();
})
.EnableSwaggerUi(c => { });
}
Request example classes
public class EchoRequestExample : IExamplesProvider
{
public object GetExamples()
{
return new EchoInput { Value = 7 } ;
}
}
public class EchoInput
{
public int Value { get; set; }
}
Action
[HttpGet]
[Route("Echo")]
[CustomApiAuthorize]
[SwaggerRequestExample(typeof(EchoInput), typeof(EchoRequestExample))]
[ResponseType(typeof(EchoServiceModel))]
public HttpResponseMessage Echo([FromUri] EchoInput model)
{
var ret = new EchoServiceModel
{
Username = RequestContext.Principal.Identity.Name,
Value = value
};
return Request.CreateResponse(HttpStatusCode.OK, ret);
}
Swagger UI shows xml comments and output metadata (model and an example containing default values), but shows no request example. I attached to process and EchoRequestExample.GetExamples is not hit.
Question: How to make SwaggerRequestExample attribute work in ASP.NET MVC 5?
Note: Windows identity is used for authorization.
I received an answer from library owner here:
Swagger request examples can only set on [HttpPost] actions
It is not clear if this is a design choice or just a limitation, as I find [HttpGet] examples also relevant.
I know the feeling, lot's of overhead just for an example, I struggle with this for a while, so I created my own fork of swashbuckle, and after unsuccessful attempts to merge my ideas I ended up detaching and renaming my project and pushed to nuget, here it is: Swagger-Net
An example like that will be:
[SwaggerExample("id", "123456")]
public IHttpActionResult GetById(int id)
{
Here the full code for that: Swagger_Test/Controllers/IHttpActionResultController.cs#L26
Wondering how that looks like on the Swagger-UI, here it is:
http://swagger-net-test.azurewebsites.net/swagger/ui/index?filter=IHttpActionResult#/IHttpActionResult/IHttpActionResult_GetById

Displaying an html page in form (error connecting to stream)

I putted an .html page in a src folder of project in order to display this page on runtime.
But I get an error on runtime that say:- Error connecting to stream.
import javax.microedition.midlet.*;
public class HtmlMidlet extends MIDlet {
public void startApp()
{
com.sun.lwuit.Display.init(this);
final com.sun.lwuit.Form form = new com.sun.lwuit.Form("");
final com.sun.lwuit.html.HTMLComponent htmlC = new com.sun.lwuit.html.HTMLComponent( );
htmlC.setRTL(true);
htmlC.setPage("jar://src/ahlam.html");
form.addComponent(htmlC);
form.setScrollable(true);
form.show( );
}
public void pauseApp()
{
}
public void destroyApp(boolean unconditional)
{
}
}
I think that the way that you are using to open your file is not the proper way. Is this html page in your folder? Where is your page? the root directory is /src from your project, why are you using jar:... try /ahlam.html only
Take a look on this page for more info and examples HTML Component

How to handle HTTP 403 with Spring Security 3.0.x

I'm facing a little issue with Spring Security 3.0.x (3.0.2 in particular at the moment). The whole application I'm working on is working perfectly except when someone who doesn't have the authorities tries to log on.
When it occurs, the users is redirected to the "welcome" page, since his username/password are valid, and he receive a cute white page with this : "Error 403: Access is denied"
So, I've been looking on the net trying to find how this behavior can be handled. So far I've come to the conclusion, please correct me if I'm wrong, that it is managed by the ExceptionTranslationFilter. But I don't quite understand how to make any good use of this information.
I've tryied to edit my SecurityContext.xml to add a access-denied-handler tag to my http tag, but it doesn't work. Do I need to add more than this tag to make it work? Is there any other possibilities to make my application more user-friendly?
Edit : I would like to redirect to a page, let's says 403.html, for example.
Sincerly,
Thanks
I still don't get why you had to implement your own access handler... I have currently faced same task:
<security:access-denied-handler error-page="/accessDenied"/> - works like charm.
Don't forget to specify handler in your Controller:
#RequestMapping(value = "/accessDenied")
public String accessDenied() {
return "accessDenied"; // logical view name
}
Update for Spring Boot(2014 Oct):
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.exceptionHandling().accessDeniedHandler(customHandler) OR .accessDeniedPage("/somePage.html").and
.formLogin()
.failureHandler(ajaxAuthenticationFailureHandler)}
Nowadays we don't really return views for such task since angular js kicks in so you can use your failure/success handler and return tailored JSON responses. For us it was sufficient to use failure handler but you get to choose where you want your control to kick in. We generally don't use view resolvers as there are UI tiles frameworks(such as angular partials) able to construct pieces into single page for you. Html pieces are stored on the server and served simply as static resources.
Lets play with Embedded Tomcat to achieve similar behavior to web.xml !
#Configuration
#EnableAutoConfiguration
public class ApplicationWebXml extends SpringBootServletInitializer {
private static final Logger LOGGER = LoggerFactory.getLogger(Application.class);
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.profiles(addDefaultProfile())
.showBanner(false)
.sources(Application.class);
}
//required for container customizer to work, the numerous tutorials didn't work for me, so I simply tried overriding the default one
#Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
return tomcat;
}
#Bean
public EmbeddedServletContainerCustomizer containerCustomizer(
) {
return new EmbeddedServletContainerCustomizer() {
#Override
public void customize(ConfigurableEmbeddedServletContainer container) {
TomcatEmbeddedServletContainerFactory containerFactory = (TomcatEmbeddedServletContainerFactory) container;
containerFactory.setSessionTimeout(1); // just for your interest, remove as necessary
containerFactory.addErrorPages(new ErrorPage(HttpStatus.FORBIDDEN,"/views/accessDenied.html"),
new ErrorPage(HttpStatus.NOT_FOUND,"/views/notFound.html"));
containerFactory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
#Override
public void customize(Connector connector) {
connector.setPort(8082);// just for your interest, remove as necessary
}
});
}
};
}
}
A cleaner way to handle error redirects is to use the <error-page> and <error-code> tags in your web.xml. See below for an example:
<!-- Custom 403 Error Page -->
<!--
NOTE: Security will throw this error when a user has been authenticated successfully
but lacks the permissions to perform the requested action.
-->
<error-page>
<error-code>403</error-code>
<location>/403.jsp</location>
</error-page>
This block of code will redirect to the specified location whenever it encounters the specified error code.
This eliminates the need for authorization code inside your application logic.
I've found how to do this. By implementing the AccessDeniedHandler interface and the corresponding handle method I can, easily, control the way the Http 403 error is handled.
This way, you can add various items in the session and then intercept them on your jsp.
The xml file then looks like this :
<sec:http>
<!-- lots of urls here -->
<sec:access-denied-handler ref="accessDeniedHandler" />
<sec:anonymous/>
</sec:http>
<bean id="accessDeniedHandler" class="foo.bar.CustomAccessDeniedHandler">
<property name="accessDeniedUrl" value="403.html" />
</bean>
The java class :
package foo.bar;
public class CustomAccessDeniedHandler implements org.springframework.security.web.access.AccessDeniedHandler {
private String accessDeniedUrl;
public CustomAccessDeniedHandler() {
}
public CustomAccessDeniedHandler(String accessDeniedUrl) {
this.accessDeniedUrl = accessDeniedUrl;
}
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
response.sendRedirect(accessDeniedUrl);
request.getSession().setAttribute("CustomSessionAttribute", "value here");
}
public String getAccessDeniedUrl() {
return accessDeniedUrl;
}
public void setAccessDeniedUrl(String accessDeniedUrl) {
this.accessDeniedUrl = accessDeniedUrl;
}
}
And a jsp example :
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:if test="${!empty CustomSessionAttribute}">
<br/>
ACCESS IS DENIED
<br/>
</c:if>
<!-- other stuff down here -->
The way to make this work is to define a handler in your entry point:
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
#Override
public void commence(HttpServletRequest request, HttpServletResponse response, org.springframework.security.core.AuthenticationException authException) throws IOException, ServletException {
if (authException != null) {
// you can check for the spefic exception here and redirect like this
response.sendRedirect("403.html");
}
}
}
You can define this as your entry point by setting this as you entry point in the xml config file:
<http entry-point-ref="customAuthenticationEntryPoint">
...
</http>
You have checked the tag in an application and to me it seems to work.
<sec:access-denied-handler error-page="/handle403Url" />
where handle403Url I want to call to handle this error (for example to show an error).
Don't forget that you have to allow this url in the filters so it can be reached by this user authority, so in the start of the flters you have to add something like this:
<sec:intercept-url pattern="/handle403Url" filters="none" />

Resources