This is a migrated thread and some comments may be shown as answers.

HtmlEncode/HtmlDecode

13 Answers 405 Views
Feature Requests
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Stuart Hemming
Top achievements
Rank 2
Stuart Hemming asked on 21 Jul 2010, 07:21 PM
Maybe I'm showing my age, but when I'm handling inputs, specifically string inputs that are going to end up going to the database I have a thing about wanting to make sure that I've done what I can to ensure that any tricks played by those playful little minxes out there aren't going to turn my data in to soup.

One of the things I tend to do as a an automatic step is call HtmlEncode on all string data going to the DB and then HtmlDecode when it comes back out.

With my DB access going through OA's persistent classes now I only have to write this once ...
[FieldAlias("description")]
public string Description
{
    get
    {
        return HttpContext.Current.Server.HtmlDecode(description);
    }
    set
    {
        description = HttpContext.Current.Server.HtmlEncode(value);
    }
}

but I wondered if it wouldn't be a nice idea for OA's designer to spot string values and provide an option to automatically add the code to encode/decode these values.

I guess there are going to be times when people don't want OA messing with their data, so it should be a optional step, a checkbox on the form, for example leading to a change in the class like this...
[FieldAlias("description")]
[AutoEncode]
public string Description
{
    get
    {
        return description;
    }
    set
    {
        description = value;
    }
}


What do you think?

-- 
Stuart

13 Answers, 1 is accepted

Sort by
0
Accepted
Serge
Telerik team
answered on 22 Jul 2010, 02:08 PM
Hi Stuart Hemming,

 The good thing about the code generation is that you can easily modify it to suite your needs. In this particular example I will show you how to modify the way OpenAccess generates string properties. You can do this in a couple of steps. 

First we need to locate the T4 templates that OpenAccess uses. The C# templates are usually located under 
C:\Program Files (x86)\Telerik\OpenAccess ORM\dsl\CodeGenerationTemplates\CSharp. What we need to modify is the Specific.ttinclude file. Note that it would be better to copy this folder and not modify the default templates. You can specify which template the code generation is using through the model settings dialog.

First you should find the InitializeDefaultUsings() method and add the System.Web using to the default usings. Your should look like this : 

private void InitializeDefaultUsings()
{
    if (Usings.Count < 1)
    {
        Usings.Add("System");
        Usings.Add("System.Data");
        Usings.Add("System.Linq");
        Usings.Add("System.Linq.Expressions");
        Usings.Add("System.Data.Common");      
        Usings.Add("System.Collections.Generic");
        Usings.Add("System.Web"); // the added using
        Usings.Add("Telerik.OpenAccess");
    }
}

Then you have to find the code for adding a property. It should look like this before any changes.

private <#= this.GetTypeStringPresentation(property) #> <#= property.FieldName #><#= initialValue #>;
 
<#+ GenerateCustomAttributes(property.Attributes); #>
public virtual <#= this.GetTypeStringPresentation(property) #> <#= property.Name #>
{
<#+
    if(property.HasGetter)
    {
#>
    get
    {
        return this.<#= property.FieldName #>;
    }
<#+
    }
    if(property.HasSetter)
    {
#>
    set
    {
        this.<#= property.FieldName #> = value;
    }
<#+
    }
#>
}

In order to make it generate code that encodes and decodes these properties you should change it to look like this.

private <#= this.GetTypeStringPresentation(property) #> <#= property.FieldName #><#= initialValue #>;
 
<#+ GenerateCustomAttributes(property.Attributes); #>
public virtual <#= this.GetTypeStringPresentation(property) #> <#= property.Name #>
{
<#+
    if(property.HasGetter)
    {
#>
    get
    {
<#+
        string type = this.GetTypeStringPresentation(property);
        if(type == "String" || type == "string")
        {
#>
        return HttpContext.Current.Server.HtmlDecode(this.<#= property.FieldName #>);
<#+
        }
        else
        {
#>
        return this.<#= property.FieldName #>;
<#+
        }
#>
    }
<#+
    }
    if(property.HasSetter)
    {
#>
    set
    {
<#+
        string type = this.GetTypeStringPresentation(property);
        if(type == "String" || type == "string")
        {
#>
        this.<#= property.FieldName #> = HttpContext.Current.Server.HtmlEncode(value);
<#+
        }
        else
        {
#>
        this.<#= property.FieldName #> = value;
<#+
        }
#>
    }
<#+
    }
#>
}

I have attached a zip file containing this modified template for you to use. Using this technique I have successfully generated properties that look like this for example : 

private string firstName;
 
public virtual string FirstName
{
    get
    {
        return HttpContext.Current.Server.HtmlDecode(this.firstName);
    }
    set
    {
        this.firstName = HttpContext.Current.Server.HtmlEncode(value);
    }
}

Please share your thoughts on this approach.

Best wishes,
Serge
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Stuart Hemming
Top achievements
Rank 2
answered on 22 Jul 2010, 02:49 PM
Serge,

Neat!

Like I said, this would be a nice addition to the product as a whole, so I'd like to suggest that your template is added to the official product.

A secondary question: is the nature of the templates documented anywhere?

--
Stuart
0
Stuart Hemming
Top achievements
Rank 2
answered on 22 Jul 2010, 03:00 PM
You can specify which template the code generation is using through the model settings dialog.
I have a sneaking suspicion I know the answer to this question...

I'm not using the Designer. I started this project before the designer could work with forward mapping which is what I'm using. I've looked for a "Model Settings" option, or anything that suggests I can change the path of any templates but can't find anything. Does this mean I can't do this?

-- 
Stuart
0
Serge
Telerik team
answered on 22 Jul 2010, 04:57 PM
Hello Stuart Hemming,

Your sneaking suspicion is right.

You mentioned the designer so I assumed even though the examples were from the Wizards you were in fact looking for domain model features. Unfortunately we do not plan on investing more time into the old approach. As to adding this in the product, at the time we think it's best to only ship the default  templates and give the chance to the community to fill this gap.

As to the nature of the T4 templates this blog post by Scott Hanselman rounds up most of the good articles about code generation. 

All the best,
Serge
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Stuart Hemming
Top achievements
Rank 2
answered on 22 Jul 2010, 05:04 PM
Your sneaking suspicion is right.
I hate it when that happens! :-)

> Unfortunately we do not plan on investing more time into the old approach.
I had guessed that too. I've been told by one of your colleagues that I should hold my water and that a conversion tool for the old forward mapping projects to the new Designer model will turn up "at some point in the future". I'll just have to carry on being the poor relation for now I guess.

As to the nature of the T4 templates this blog post by Scott Hanselman rounds up most of the good articles about code generation. 
I've added that to my "to read" list.

Thanks again Serge.

-- 
Stuart
0
Serge
Telerik team
answered on 23 Jul 2010, 03:44 PM
Hello Stuart Hemming,

Actually the convert tool is already here, but I suspect it will not be of any help to you as it is only working with models created trough the Reverse Mapping Wizard.

However you can check this blog post out.

Be that as it may, it shouldn't be too hard to manually convert your project and I will be glad to help you with this task, if you have the time of course. 

Best wishes,
Serge
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Stuart Hemming
Top achievements
Rank 2
answered on 23 Jul 2010, 03:56 PM
> it shouldn't be too hard to manually convert your project and I will be glad to help you with this task,
That's very kind.

> if you have the time of course. 
Indeed I do.

I have to say that the Model isn't very big at all ATM, just a dozen or so classes.

So, where do I start? Do we do it here in the forum?

-- 
Stuart
0
Serge
Telerik team
answered on 23 Jul 2010, 08:00 PM
Hello Stuart Hemming,

 I do not see a reason why not. However a few points I would like to make before we start. We can convert your solution to use the new domain model but any changes you would want to your model will have to go through the designer. This means that you will not exactly be using forward mapping but modifying your model trough the designer.

So first you should know that the old approach and the designer cannot co-exist in a single project. They use different enhancers and which exclude each other. The easiest way for you will be to just create a new DAL project and add a new domain model. Configure it to connect to the same database and choose all object needed. Then reverse map your objects. 

I think this would be the place to check if the class and property names are the same as before. If you have only been using the forward mapping this would likely not be the case. However renaming properties shouldn't pose as a problem.

At this point you will have two models that should look exactly the same. However as you might have noticed the entry points to OpenAccess are now different. The scopes previously used are nowhere to be found in the new model. You have a choice here, if you have a lot of code that uses scopes that you do not want to change you can implement a ObjectScopeProvider that would be exactly the same as the old one with the exception of the static Database() method. The new implementation of this method you can find in the blog post about the Upgrade Wizard. This approach is left there for backwards compatibility so that you are able to still run your existing code.

However it shouldn't be to hard to convert code using scopes to using the new context. Essentially what you need to change is the initialization of the scope to initialize a context, remove the Transaction.Begin statements, change scope.Extent<Product>() to context.Products for the type named Product, change scope.Add to context.Add. What is left is to change scope.Transaction.Commit() to context.SaveChanges() and if you have used it the scope.Transaction.Rollback() to context.ClearChanges().

It would be best in this situation to remove any references to the project containing the Wizards generated model to make sure everything works with the new context. Also in order to get things working with the connection strings you have to copy the connection string from
app.config in the project containing the .rlinq and paste into the config file of the executing project.

This should be enough to get you started. 

Regards,
Serge
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Stuart Hemming
Top achievements
Rank 2
answered on 23 Jul 2010, 10:55 PM
We can convert your solution to use the new domain model but any changes you
> would want to your model will have to go through the designer. This means that
> you will not exactly be using forward mapping but  modifying your model trough
> the designer.
I see no problem with that.

> The easiest way for you will be to just create a new DAL project and add a new
> domain model. Configure it to connect to the same database and choose all
> object needed. Then reverse map your objects. 

I've done that and it's made a dreadful job of it.

Let's look at some of the issues:
I have a class "Contact". There are 2 additional classes, "Tutor" and "Student" which inherit from this. There are just a couple of properties in each of the 2 inherited classes so, when I created them using the Forward-Mapping wizard, I opted for flat mapping,

When the I created by Domain Model by pointing it at my existing DB, it created 3 classes, but all three had properties in from all of the others.

In my original model I have a class "School". A School can have many "Locations" and each Location has an "Address". None these relationships (or any of the others that exist in the original model) made it in to the design of the new Domain Model.

Maybe my expectations were too high. I expected to have to do something to the generated Domain Model to get it working, but this leaves me thinking that I would be better off starting from fresh.

-- 
Stuart
0
Jordan
Telerik team
answered on 28 Jul 2010, 07:52 AM
Hi Stuart Hemming,

Regarding the lost relationships that you mention:
In a database relationships are usually represented by foreign key constraints.
And by default, the forward mapping wizard does not always create these constraints in the database.
And if there are no foreign key constraints in the database there is no enough information for the "add new domain model" wizard to create the associations between classes.
You can make the forward mapping wizard to always create foreign key constraints using the dbNullForeignKey option in your app.config file. You can find more information in this forum thread:
http://www.telerik.com/community/forums/orm/development/foreign-key-constraint-on-null-column-in-mssql-2005.aspx

Regarding your inheritance issues:
It is normal that the "add new domain model" wizard did not guess the inheritance from the database and thus did not create inherited classes. This functionality is not implemented currently.
We are planning to do some improvements in that direction for the Q3 2010 release of OpenAccess.

Sincerely yours,
Jordan
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Stuart Hemming
Top achievements
Rank 2
answered on 29 Jul 2010, 09:36 PM
Jordan

Thanks again for the comments. I have to say that I've abandoned just about any hope of using the designer for building a model. I just can't bring myself to believe that it's fit for the purpose in its current incarnation.

I'll just go on doing things with the forward mapping wizard at least until Q3 gets here.

-- 
Stuart
0
Accepted
Jordan
Telerik team
answered on 30 Jul 2010, 11:09 AM
Hi Stuart Hemming,

I have to admit that the forward mapping functionality of the visual designer is lacking a couple of features that will make it more usable. We are currently working on improving the experience there.
I hope that after we get out the Q3 2010 release of OpenAccess you will find the visual designer fit for your needs.

Sincerely yours,
Jordan
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Stuart Hemming
Top achievements
Rank 2
answered on 03 Aug 2010, 08:56 PM
My breath has never been so baited! :-)

-- 
Stuart
Tags
Feature Requests
Asked by
Stuart Hemming
Top achievements
Rank 2
Answers by
Serge
Telerik team
Stuart Hemming
Top achievements
Rank 2
Jordan
Telerik team
Share this question
or