In the shopping basket of my site, i need to allow a form POST of XML coming from a third-party service.
The possible solutions i can find is for webforms and < Umbraco 7.
I'm aware that you can disable page validation entirely, but that's not an option in my case.
Does someone know the equivalent way of using the control <umbraco:DisableRequestValidation runat="server"/> in MVC?
for security reason, I would suggest try use [AllowHtml] on property which would contain the xml content
so say you viewmodel has property call ThirdPartyContent which will have xml:
public class VM
{
public string Name { get; set; }
[AllowHtml]
public string ThirdPartyContent { get; set; }
}
this implicit state which property you are aware will contain potential malicious content (which is angle bracket)
[ValidateInput(false)] does the trick but will assume all property may contain xml content which may not be good thing
more info checkout this SO answer which say the difference between [AllowHtml] and [ValidateInput(false)]
ValidateInput(false) vs AllowHtml
I found the answer to my own question.
It's possible to set the [ValidateInput(false)] annotation on RenderMvcControllers. So you can do it per document type which is kinda nice.
I'll leave the answer here in case someone else needs to do the same thing.
Related
I'm using ASP.NET Core MVC 2. I need to operator can change some elements of Models or view codes. How I can code or design for it.
For example: I have a "news" model and I want to operator (final user of website, who can't code or access to visual studio) can add this to "news" model:
public string ImageUrl { get; set; }
and also can change the database without coding.
Thanks
If you want to design a completely extensible model, you could use something called Entity–attribute–value model (EAV).
Your model might have a couple common attributes like Title and Summary. Then you might have a list of Custom Fields, the first of which could be ImageUrl. You could create your own class called CustomField or something similar, which would have properties such as FieldName, and DataType.
public string Title { get; set; }
public string Summary { get; set; }
public List<CustomField> CustomFields { get; set; }
You would then have a table full of custom field values and the tables they belong to. It gets pretty complex.
When you want to automatically reflect your model changes to the database, you will need an ORM framework like EF (Entity Framework). You can check more here.
In order for your case to happen is to build your own configuration platform that may use several tools and mechanincs that will allow you to generate code and then compile it. Such as T4 and more.
In general, this is a very hard task to accomplish and even big experienced teams would have troubles to build something similar.
I can not post any code, as this would only seem a desperate approach.
I'm after a friendly way to handle A potentially dangerous Request.Form value was detected
I want to be able to validate it myself and return my own validation message.
I was thinking of using the [AllowHtml] attribute then checking to see if the value contains potentially dangerous content via another ValidateAttribute or using IValidatableObject.
Is there a built in helper to manually validate the property's value?
Is there a better way of doing what I'm trying to achive?
Why not use [AllowHtml] together with another validation like that:
[AllowHtml]
[RegularExpression("(\<[a-zA-Z\!\/\?]|&#|script\s*\:)", ErrorMessage = "Invalid characters or whatever your message is")]
public string Description { get; set; }
See Security Extensibility in MVC4 document for more info. Hope it helps!
how can I use a Required Validation in a property Prop2 only if the Prop1 is true?
Ex:
public bool Prop1 { get; set; }
[Required] // I need this validation only if the Prop1 is true.
public string Prop2 { get; set; }
Any idea? I need on client and server side.
Thanks
You could use MVC FoolProof Validation framework
It has useful feature like
[RequiredIf]
[RequiredIfNot]
[RequiredIfTrue]
[RequiredIfFalse]
[RequiredIfEmpty]
[RequiredIfNotEmpty]
[RequiredIfRegExMatch]
[RequiredIfNotRegExMatch]
[Is]
[EqualTo]
[NotEqualTo]
[GreaterThan]
[LessThan]
[GreaterThanOrEqualTo]
[LessThanOrEqualTo]
Hope this would help you!
There are two parts to this. First, you have to write a required attribute that's only required if the other property meets your criteria.
You'd have to do something like:
public class RequiredComparerAttribute : RequiredAttribute
{
public OtherProperty { get; set; }
public override bool IsValid(object value)
{
// TODO: use reflection to validate other property as PropertyInfo
// or validate it's value after it is decided to be valid
foreach (ValidationAttribute va in property
.GetCustomAttributes(typeof(ValidationAttribute), true)
.OfType<ValidationAttribute>())
{
if (!va.IsValid(value))
{
return false; // not required
}
}
return true; // required
}
}
Then, in Application_Start in the Global.asax, you'll have to register the validator, which you can just reuse the RequiredAttribute's validator:
DataAnnotationsModelValidatorProvider
.RegisterAdapter(typeof(RequiredComparerAttribute),
typeof(RequiredAttributeAdapter));
If you want to add your own validator, you'll have to write a custom validator. Phil Haack has an example on his blog: http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx
Edit: Take a look at CompareAttribute in .NET Reflector for a sense of how to get the value of the OtherProperty. CompareAttribute also implements IClientValidatable to provide those validation rules needed on the client side.
I don't think CompareAttribute will work for you because you have to validate that a value is required based on content of another property, not compare the equality of two properties.
Edit2: What does the Validation provider do?
It adds rules to the form and provides messages for those rules. You can see exactly how the RequiredAttributeAdapter does this by downloading the MVC 3 source. To understand what it does on the client side, you can open the MVC 3 page in Google Chrome, hit CTRL+SHIFT+J to bring up a developer tools window and enter:
$('form:first').data().unobtrusiveValidation.options
The rules object inside options specifies how to validate each item and the message object specifies the error message that will be displayed for each validation error.
Edit3: Full example
Since answering this question, I've written a blog post with a full example of creating a custom attribute on the client (unobtrusive validation) and server. The blog post is here. This example is for a 'contains' attribute, but it should be pretty easy to modify to become a required comparison.
You can write a custom validator do to this job.
Let me know if you need help to do it.
How do I integrate ReportViewer in asp.net MVC project?
I want to add business objects of MVCProject.Model namespace. ReportViewer allows Business objects of DataSet.
Is it possible to choose other data source, like LinqDataSource, or Direct object to LINQ-to-SQL class objects?
What would be the best solution to add reports in an MVC project?
An alternative way to do this would be to generate the report on the reporting server, then stream it to the mvc app as a PDF.
I got an idea that is not tested but may work.
1- Place report viewer control in a standard ASP.Net web form page (e.g. ReportViewer.aspx)
2- Under your MVC, add an iframe that references to this ReportViewer.aspx page
3- Pass parameters to the page using sessions or query strings
Let me know if th is works
It's gonna be tough. First, you need ViewState so you'll need to host the report in a regular WebForms page. This isn't too bad though - WebForms and MVC work fine side-by-side.
The hard part is binding to real IEnumerable objects and not those phoney-baloney ObjectDataSources.
The first step is to build up a report data model. You can do this in code, with queries, whatever, however you want. A structure something like this (but obviously much bigger) is typical:
public class ReportSource
{
public Floogle[] Floogles { get; set; }
}
public class Floogle
{
public Doodad[] Doodads { get; set; }
public string Text { get; set; }
}
public class Doodad
{
public int Number { get; set; }
}
The trick is to use a BindingSource control in your report and set the DataSource property to typeof(ReportSource) - yes, the data source is the type of your report model.
When designing your report you won't get a lot of richness, but you'll be able to do it.
As far as third party reporting solutions go, we've found Telerik's to be the best option.
I've got a small project I threw up on codeplex that is an mvc project with a report.
http://mvctaskmanagement.codeplex.com/
Basically since I do dev on an XP box, my web form had to get pushed to a separate project. Since I have a service layer proj, I stuck it in there.
From there I call my report via a ajax post shooting the params over to the report page, which then passes it down to the same service layer used to generate the preview.
Good luck!
I have certain panels on my page that are hidden under certain circumstances.
For instance I might have a 'billing address' and 'shipping address' and I dont want to validate 'shipping address' if a 'ShippingSameAsBilling' checkbox is checked.
I am trying to use the new DataAnnotations capabilities of ASP.NET MVC 2 (preview 1) to achieve this.
I need to prevent validation of the 'shipping address' when it is not displayed and need to find the way way to achieve this. I am talking mainly server side as opposed to by using jquery.
How can I achieve this? I have had several ideas, related to custom model binding but my current best solution is below. Any feedback on this method?
For the CheckoutModel I am using this approach (most fields hidden):
[ModelBinder(typeof(CheckoutModelBinder))]
public class CheckoutModel : ShoppingCartModel
{
public Address BillingAddress { get; set; }
public Address ShippingAddress { get; set; }
public bool ShipToBillingAddress { get; set; }
}
public class Address
{
[Required(ErrorMessage = "Email is required")]
public string Email { get; set; }
[Required(ErrorMessage = "First name is required")]
public string FirstName { get; set; }
[Required()]
public string LastName { get; set; }
[Required()]
public string Address1 { get; set; }
}
The custom model binder removes all ModelState errors for fields beginning with 'ShippingAddress' if it finds any. Then 'TryUpdateModel()' will return true.
public class CheckoutModelBinder : DefaultModelBinder
{
protected override void OnModelUpdated(ControllerContext controllerContext,
ModelBindingContext bindingContext) {
base.OnModelUpdated(controllerContext, bindingContext);
var model = (CheckoutModel)bindingContext.Model;
// if user specified Shipping and Billing are the same then
// remove all ModelState errors for ShippingAddress
if (model.ShipToBillingAddress)
{
var keys = bindingContext.ModelState.Where(x => x.Key.StartsWith("ShippingAddress")).Select(x => x.Key).ToList();
foreach (var key in keys)
{
bindingContext.ModelState.Remove(key);
}
}
}
}
Any better solutions?
http://bradwilson.typepad.com/blog/2009/04/dataannotations-and-aspnet-mvc.html
I can see your predicament. I'm looking for other validation solutions also with regard to complex validation rules that might apply to more than one property on a given model object or even many properties from different model objects in a object graph (if your unlucky enough to be validating linked objects like this).
The limitation of the IDataErrorInfo interface is that a model object satisfies the valid state simply when none of the properties have errors. This is to say that a valid object is one where all of it's properties are also valid. However, i may have a situation where if property A, B and C are valid - then the whole object is valid.. but also if property A is not valid but B and C are, then the object satisfies validity. I simply have no way of describing this condition/rule with the IDataErrorInfo interface / DataAnnotations attributes.
So i found this delegate approach. Now many of the helpful advancements in MVC didn't exist at the time of writing this article but the core concept should help you. Rather than using attributes to define the validation conditions of an object we create delegate functions that validate more complex requirements and because they're delegated we can re-use them. Sure it's more work, but the use of delegates means that we should be able to write validation rule code once and store all the validation rules in the one place (maybe service layer) and (the kool bit) even use the MVC 2 DefaultModelBinder to invoke the validation automatically (without heaps of checking in our controller actions - like Scott's blog says we can do with DataAnnotations. Refer to the last paragraph before the 'Strongly Typed UI Helpers' heading)!
I'm sure you can beef the approach suggested in the above article up a little with anonymous delegates like Func<T> or Predicate<T> and writing custom code blocks for the validation rules will enable cross-property conditions (for example the condition you referred to where if your ShippingSameAsBilling property is true then you can ignore more rules for the shipping address, etc).
DataAnnotations serves to make simple validation rules on objects really easy with very little code. But as your requirements develop you will need to validate on more complex rules. The new virtual methods in the MVC2 model binder should continue to provide us with ways of integrating our future validation inventions into the MVC framework.
Make sure the fields you don't want validated are not posted to the action. We only validate the fields that were actually posted.
Edit: (by questioner)
This behavior has changed in MVC2 RC2 :
Default validation system validates
entire model The default validation
system in ASP.NET MVC 1.0 and in
previews of ASP.NET MVC 2 prior to RC
2 validated only model properties that
were posted to the server. In ASP.NET
MVC 2, the new behavior is that all
model properties are validated when
the model is validated, regardless of
whether a new value was posted.
Applications that depend on the
ASP.NET MVC 1.0 behavior may require
changes. For more information about
this change, see the entry Input
Validation vs. Model Validation in
ASP.NET MVC on Brad Wilson’s blog.
For the more complex cases I moved away from simple DataAnnotations to the following: Validation with visitors and extension methods.
If you want to make use of your DataAnnotations you would replace something like the following:
public IEnumerable<ErrorInfo> BrokenRules (Payment payment)
{
// snip...
if (string.IsNullOrEmpty (payment.CCName))
{
yield return new ErrorInfo ("CCName", "Credit card name is required");
}
}
with a method to validate a property by name via DataAnnotations (which I don't have atm).
I created a partial model binder that only validates the keys that were submitted. For security reasons (if I was going to take this a step farther) I'd create a data annotation attribute that marks which fields are allowed to be excluded from a model. Then, OnModelUpdated check field attributes to ensure there is no undesired underposting going on.
public class PartialModelBinder : DefaultModelBinder
{
protected override void OnModelUpdated(ControllerContext controllerContext,
ModelBindingContext bindingContext)
{
// default model binding to get errors
base.OnModelUpdated(controllerContext, bindingContext);
// remove errors from filds not posted
// TODO: include request files
var postedKeys = controllerContext.HttpContext.Request.Form.AllKeys;
var unpostedKeysWithErrors = bindingContext.ModelState
.Where(i => !postedKeys.Contains(i.Key))
.Select(i=> i.Key).ToList();
foreach (var key in unpostedKeysWithErrors)
{
bindingContext.ModelState.Remove(key);
}
}
}
This isn't related to DataAnnotations but have you looked at the Fluent Validation project? It gives you fine grain control over your validation and if you have object-to-object validation an aggregate object of the two objects will get you going.
Also it seems to have been build with MVC in mind but it also has its own "runtime" so that you can use it in other .NET applications as well which is another bonus in my book.