Model Validation without the ValidationSummary? - html

I have a LoginModel for my Login Action, but I'm wanting to use just HTML.
Example...
public class LoginModel
{
[Required]
public string Email { get;set; }
}
in my HTML, I have
<input type="text" value="" name="Email">
This is because I'm going to be storing my HTML in my database, problem I'm having is, how do I get model validation without using Html.ValidationSummary()?
I was hoping I could just do <div class="validation-summary-errors"></div>
As this is what is in the HTML, but does not work..
Ideas?

Regardless of where you store your HTML the validation is done on the client side. There are various posts on how to use the virtual path provider to store your views somewhere else (DB) and then validation should still work fine. I think I'm missing why it's not working for you though so I have to imagine you aren't using the path provider to find your views.
Edit
Seems you want to inject messages into a Div. This wont happen automaticaly unless you work some magic in the path provider. Use your own helper method in the view to avoid hacks or just use what's provided by default. If you really want to do it render your view in your controlllet and search for your Div pattern to replace.
custom ValidationForMessage helper removing css element
Note Darin's method
var expression = ExpressionHelper.GetExpressionText(ex);
var modelName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(expression);
var modelState = htmlHelper.ViewData.ModelState[modelName];
without access to ViewContext in your controller you can only render your html for your View. However, somewhere in your view you need (as far as I can tell) a helper method to stick your error collection into ViewData.
Your Virtual Path Provider may have to inject this helper method into your view text so it is there for Razor to parse. Actually - duh. This may be much easier. Your provider may be able to just simply read your html from the database, find the div, and inject the #Html.ValidationSummary into that div. I believe this would work. Why not just put the validation summary in there though if its going to end up there in the end anyways (essentially)

Related

how to interact with HTML forms in delphi using TChromium

i need to update the design of a browser in delphi7 I was using the twebbrowser but he had many problems with javascript and navigation.. so i decide to migrate to Chromium. the problem is that I cannot find code on these components. does anyone know which command would be equivalent to this one in tchromium:
OleObject.Document.all.Item ('ElementbyId', 0) .value: = 'edit1.text';
i need to transfer a text from memo to textarea in html form and at the end send a click on the button on the html form. if anyone knows the commands and can share I appreciate it.
A more flexible alternative than DOM access could be to perform this in Javascript, with the ExecuteJavaScript method of TChromium.
From your summary description, the JS could be something like
document.getElementById('yourtextarea').value = <JSON stringified content of your memo>;
document.getElementById('yourform').submit();
Alternatively, you could implement a JS function in your HTML, and call it with ExecuteJavascript, this way there would not be anything specific (besides the function name) on the Delphi side, and the HTML would be free to evolve.
function setTextAreaAndSubmit(value) {
document.getElementById('yourtextarea').value = value;
document.getElementById('yourform').submit();
}

ASP.NET Core - Set Layout Page Outside of the View

I have an ASP.NET Core 2.0 application and I'm trying to set the layout page a view should use outside of the view. That way I won't have to keep repeating the same code at the top for all of my views.
I can achieve this by inheriting all of my views from the following base class which sets it within the constructor:
public class RazorPage<TModel> : Microsoft.AspNetCore.Mvc.Razor.RazorPage<TModel> {
public RazorPage() {
var theme = "Theme1;"
Layout = $"~/Areas/{theme}/Views/Shared/_Layout" + RazorViewEngine.ViewExtension;
}
}
This works fine however the name of theme changes based on the current URL. I figured I could do this by accessing the current context, however if I call the Context property within the constructor it returns null.
There doesn't appear an appropriate method to override where I could set the Layout property and have access to the current request context.
Does anyone know an alternative way of doing?
Please note that I am aware I could achieve this with _ViewImports/_ViewStart files but due to the structure of my application it would require me to have duplicate files and also I don't like having business logic within my views.
I used an IViewLocationExpander (as suggested by #valery.sntx) to specify where to look for my theme's shared views which changes based on the current URL.
I then auto generated a _ViewStart file using an IFileProvider and simply set it's content to:
#{
Layout = "_Layout";
}
The second part is optional but it saved me from having to create multiple _ViewStart files due to the way my application is designed.

MVC6 Routing Issue

I'm new to MVC coding, and have been at this issue for a couple days now. I'm having trouble setting up multiple routing schemes, and having them work as intended. Here is what I've got.
Framework
Products/Info.cshtml
Products/Edit.cshtml
Model
ProductCategory.Id
ProductCategory.CategoryName
What I'm wanting to do is be able to have 2 different routing schemes in place
Products/Edit/Id
Products/Info/CategoryName
So here is how I'm structuring the tags in the documents
For Products/Edit/Id
< a asp-controller="Products" asp-action="Edit" asp-route-id="#item.Id">Edit< /a>
For Products/Info/CategoryName
< a asp-controller="Products" asp-action="Info" asp-route-category="#item.CategoryName">#item.CategoryName< /a>
So the thing is, this will actually work, functionally, but my hyperlinks for the Products/Info/CategoryName get rendered as query strings rather than the more user friendly version, for instance one category is "Fireplaces", so my links for Info become
Products/Info?category=Fireplaces
instead of what I'm wanting
Products/Info/Fireplaces
How can I configure my routes so that the Controller/Action/Parameter call works for both? I've already tried adding specific routes to app.UseMvc(), and again they work functionally, but the Info links still render out as query strings.
Ok, finally got to the bottom of it. Rather than trying to define routes the old way, with app.UseMvc(), I was able to use the new DataAnnotations in the Controller class to define the route, which resulted in creating user friendly links like I wanted, rather than the query string links. So for my Info() method in my controller class, I changed to look like
[HttpGet]
[ActionName("Info")]
[Route("Products/Info/{category}")]
public IActionResult Info(string category)
{
.....
return View(productCategory);
}

Create Dynamic View with static HTML in MVC

I have been researching dynamic content for MVC views and partial views but have not successfully found an architecture to fit my needs.
Basically I am required to create a landing page based on parameters pass by the URL.
For basics
http://mydns.com/myconroller/myview/?landingpage=Param1
The controller will need to find the HTML that will be used to create the view.
The view is going to be different based on the landing page.
(for the sake of the question, I am using landingpage as an example)
My goal is to be able to deploy a Landing page and based on the URL use that HTML Landing page in the view based on the landingpage parameter that is passed.
There are other views that are working currently in the controller. I am trying to add functionality to be able to add a new one time page without having to recompile.
I have searched through various ideas on how to load dynamic views but cannot seem to find a solution that fits this need based on what I have read.
I can possibly RedirectToAction but I am still in the dark on where to deploy and I am getting several problems with Razor as it is not in the shared directory and then I am stuck with deployment issues as I want to organize the landing pages differently than I am organizing the views.
Solution:
I decided to take a different approach and use the ContentResult Action in the controller. I still have the Main View and I use the HTML extensions to render the HTML pages that I have deployed in my customer's directory.
#{
Html.RenderAction("LandingPageContent", "Controller", Model);
}
Then in the controller I load the HTML directly and return the ContentResult
public ContentResult LandingPageContent(object model, FormCollection collection)
{
MySRCHelper helper = new MySRCHelper();
ContentVariables variables = helper.getContentSRC(model.EntryCode);
model.ContentSRC = variables.LandingPageSRC;
return Content(System.IO.File.ReadAllText(Server.MapPath(model.ContentSRC)));
}
I can then configure the path to the raw HTML file to be used and it will be loaded into the View. The View can then house all of the paths to load jQuery, CSS and other necessary javascript to integrate with the raw HTML and allow me to deploy the HTML files into any directory structure that I want. The configuration XML file allows me to find XML elements and use those values for any HTML that I am looking for, like a welcome and thank you page. The helper object will open the XML and find the configuration based on the parameters passed to the View.
<ContentLandingItem entrycode="1" customerID="Cutomer1">
<ContentLandingPageSRC>~/Customers/Customer1/Customer1Landing.htm</ContentLandingPageSRC>
<ContentThankyouSRC>~/Content/Default/GenericThankyou.htm</ContentThankyouSRC>
</ContentLandingItem>
<ContentLandingItem entrycode="2" customerID="Cutomer2">
<ContentLandingPageSRC>~/Customers/Customer2/Customer2Landing.htm</ContentLandingPageSRC>
<ContentThankyouSRC>~/Customers/Customer2/Customer2Thankyou.htm</ContentThankyouSRC>
</ContentLandingItem>
The view still performs its duties and works independently on it own letting the raw HTML decorate the View. The model is still intact and can be used as I wish. The FormCollection is there in case a form submit posts the values to the view and provides some things that I omitted from this question as it did not pertain to this subject.
I don't want to answer my own question and I found the pieces that helped me on another site, so I am putting what I did here in case anyone needs this functionality.
This sounds like using the you can inherit from the virtual path provider view engine and decide based on the URL parameters (or other) which view to return. Some example that you can adjust to your needs:
public class CustomViewEngine : VirtualPathProviderViewEngine
{
public MyViewEngine()
{
this.ViewLocationFormats = new string[] { "~/Views/{1}/{2}.mytheme ", "~/Views/Shared/{2}.mytheme" };
this.PartialViewLocationFormats = new string[] { "~/Views/{1}/{2}.mytheme ", "~/Views/Shared/{2}. mytheme " };
}
protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
{
var physicalpath = controllerContext.HttpContext.Server.MapPath(partialPath);
return new RazorView(controllerContext, physicalpath);
}
protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
{
var physicalpath = controllerContext.HttpContext.Server.MapPath(viewPath);
return new RazorView(controllerContext, physicalpath);
}
}
In there you can return a RazorView or WebFormView and set your desired path for the view to use.

HTML_purifier stripping display:none css from images, even with CSS.AllowTricky set to True?

That title is probably a bit confusing so let me elaborate.
I'm using HTML_purifier to clean up user input, although in this case the only user who will be using it will be myself (its in password protected folders). A long story short I would like to be able to add in image tag code to a web form, then on the page that it sends too use the code to display said image.
However i need the image tag to have css attributes added to it, one of which is
display:block
Anyway by default HTML_purifier removes this, detailed here because of the CSS.allowTricky option. As i understand it if you set the CSS.allowTricky option to True, then it should allow
display:block
However after doing this its still removing it, just wondering if anybody has done this before as i can't find much documentation about it on the web? Its not generating any errors in syslog, so im assuming that its the correct implementation but isn't working as expected.
My code at the moment.
include('HTMLPurifier.standalone.php');
$config = HTMLPurifier_Config::createDefault();
$config->set('CSS.AllowTricky', true);
* UPDATE **
The code should pass the config object (which the code already set) to the html purifier object. Putting it together it should look something like this.
include('HTMLPurifier.standalone.php');
$config = HTMLPurifier_Config::createDefault();
$config->set('CSS.AllowTricky', true);
$purifier = new HTMLPurifier($config);
Duplicate of http://htmlpurifier.org/phorum/read.php?3,6724 (solution was passing the config object to the HTML Purifier object so that the config actually got applied.)