Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Dec 14, 2018. It is now read-only.
/MvcPublic archive
This repository was archived by the owner on Dec 14, 2018. It is now read-only.

ExpressionTextCache is case insensitive: TextboxFor(x=>x.name) and TextboxFor(x=>x.Name) produce the same html #6349

Closed
Assignees
dougbu
Milestone
@IGionny

Description

@IGionny

I think that there is a bug withExpressionTextCache used to manage expressions into Html.EditorFor...IF i visti a page with Html.EditorFor(x=>x.name) AND after a page with Html.EditorFor(x=>x.Name) (in 2 different model). ..the result will be the same: <input name="name" ...all in lowercase (like thefirst lamda expression resolved).

I repro the problem via a test website with 2 model:
public class Product { public string Name { get; set; } }
public class ProductLower { public string name { get; set; } }

A controller with 2 actions:
public IActionResult Product() { var model = new Product(); return View(model); }

public IActionResult ProductLower() { var model = new ProductLower(); return View(model); }

and 2 views:

== [Product] ==

@{    ViewData["Title"] = "Home Page";}@model Example_Models.Models.ProductPRODUCT<br />@Html.EditorFor(x => x.Name)

== [ProductLower] ==

@{    ViewData["Title"] = "Home Page";}@model Example_Models.Models.ProductLowerLOWER<br />@Html.EditorFor(x => x.name)

If you visit ProductLower page and AFTER the Product page, the output of the @Html.EditorFor will be the same: <input id='name' name='name'...

I also take the tests for the ExpressionTextCache and put the 'wrong-case' to proof this:

//https://github.com/aspnet/Mvc/blob/2cabd589ac6a2fcd88b3c23aa50541536d2c8b71/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/ExpressionHelperTest.cs

edit the NonEquivalentExpressions adding

(Expression<Func<TestLowerModel, string>>) (model => model.name),(Expression<Func<TestModel, string>>) (model => model.Name)

full code:

//https://github.com/aspnet/Mvc/blob/2cabd589ac6a2fcd88b3c23aa50541536d2c8b71/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/ExpressionHelperTest.cs    public class ExpressionTextCacheTests    {        private readonly ExpressionTextCache _expressionTextCache = new ExpressionTextCache();        public static TheoryData<Expression, Expression> NonEquivalentExpressions        {            get            {                var value = "test";                var key = "TestModel";                var Model = "Test";                var myModel = new TestModel();                return new TheoryData<Expression, Expression>                {                   //ADDED CASE                    {                        (Expression<Func<TestLowerModel, string>>) (model => model.name),                        (Expression<Func<TestModel, string>>) (model => model.Name)                    },                    {                        (Expression<Func<TestModel, Category>>) (model => model.SelectedCategory),                        (Expression<Func<TestModel, CategoryName>>) (model => model.SelectedCategory.CategoryName)                    },                    {                        (Expression<Func<TestModel, string>>) (model => model.Model),                        (Expression<Func<TestModel, string>>) (model => model.Name)                    },                    {                        (Expression<Func<TestModel, CategoryName>>) (model => model.SelectedCategory.CategoryName),                        (Expression<Func<TestModel, string>>) (model => value)                    },                    {                        (Expression<Func<TestModel, string>>) (testModel => testModel.SelectedCategory.CategoryName                            .MainCategory),                        (Expression<Func<TestModel, string>>) (testModel => value)                    },                    {                        (Expression<Func<IList<TestModel>, Category>>) (model => model[2].SelectedCategory),                        (Expression<Func<TestModel, string>>)                        (model => model.SelectedCategory.CategoryName.MainCategory)                    },                    {                        (Expression<Func<TestModel, int>>) (testModel => testModel.SelectedCategory.CategoryId),                        (Expression<Func<TestModel, Category>>) (model => model.SelectedCategory)                    },                    {                        (Expression<Func<IDictionary<string, TestModel>, string>>) (model => model[key].SelectedCategory                            .CategoryName.MainCategory),                        (Expression<Func<TestModel, Category>>) (model => model.SelectedCategory)                    },                    {                        (Expression<Func<TestModel, string>>) (m => Model),                        (Expression<Func<TestModel, string>>) (m => m.Model)                    },                    {                        (Expression<Func<TestModel, TestModel>>) (m => m),                        (Expression<Func<TestModel, string>>) (m => m.Model)                    },                    {                        (Expression<Func<TestModel, string>>) (m => myModel.Name),                        (Expression<Func<TestModel, string>>) (m => m.Name)                    },                    {                        (Expression<Func<TestModel, string>>) (m => key),                        (Expression<Func<TestModel, string>>) (m => value)                    }                };            }        }        [Theory]        [MemberData(nameof(NonEquivalentExpressions))]        public void GetExpressionText_CheckNonEquivalentExpressions(LambdaExpression expression1,            LambdaExpression expression2)        {            // Act - 1            var text1 = ExpressionHelper.GetExpressionText(expression1, _expressionTextCache);            // Act - 2            var text2 = ExpressionHelper.GetExpressionText(expression2, _expressionTextCache);            // Assert            Assert.NotEqual(text1, text2, StringComparer.Ordinal);            Assert.NotSame(text1, text2);        }        private class TestLowerModel        {            public string name { get; set; }        }        private class TestModel        {            public string Name { get; set; }            public string Model { get; set; }            public Category SelectedCategory { get; set; }            public IList<Category> PreferredCategories { get; set; }        }        private class Category        {            public int CategoryId { get; set; }            public CategoryName CategoryName { get; set; }        }        private class CategoryName        {            public string MainCategory { get; set; }            public string SubCategory { get; set; }        }    }

I found a workaround:

public class FixedHtmlHelper<TModel> : HtmlHelper<TModel>   {       public FixedHtmlHelper(IHtmlGenerator htmlGenerator, ICompositeViewEngine viewEngine,           IModelMetadataProvider metadataProvider, IViewBufferScope bufferScope, HtmlEncoder htmlEncoder,           UrlEncoder urlEncoder, ExpressionTextCache expressionTextCache) : base(htmlGenerator, viewEngine,           metadataProvider, bufferScope, htmlEncoder, urlEncoder,//NEW INSTANCE EACH TIMEnew FixedExpressionTextCache())       {       }   }

In startup.cs:

 public void ConfigureServices(IServiceCollection services)        {            services.AddMvc();            services.AddTransient(typeof(IHtmlHelper<>), typeof(FixedHtmlHelper<>));

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions


    [8]ページ先頭

    ©2009-2025 Movatter.jp