There is view somewhere inside episrever client resources called InputFragment.ascx. it's used to render inputs and is responsible for this faulty rendering.
it renders ids as follows:
<% string inputId = "Input_" + new Random(DateTime.Now.Millisecond).Next(Int32.MaxValue); %>
Random is recreated each time and if time hasn't changed it will produce same value.
Yuo should simply create your own view with some other way to gerate id's, for example use static random suorce or guids.
I'm having the same issue where the IDs for the fields are all different in dev but are the same when deployed. Why would this be different between environments? I'd rather not create the view as described as if it works on one platform it should work on another.
As you see, random is created with milisecond as seed, so if dev environment is slow enough so that time happens to change between subsequent inputs, then the ids will differ. In production everything is most probably fast enough, so the milisecond will be the same and id will be the same.
Hi there and thanks for the response. I'm now looking at creating my own view, I presume I need to add this to the project and then set up a virtualPathMapping in EPiServerFramework.config to point to my view? If so how do I determine the virtual path that is currently being used.
I've found the default InputFragment.ascx file in the zip file EPiServer.Shell.UI.zip (under \Util\Views\Shared\EditorTemplates)
The only thing you have to do is create your own view, for example InputFragment.cshtml (or .ascx), and put it in ~/Views/Shared/EditorTemplates/ in your project and make sure the PartialViewLocationFormats of your view engine includes "~/Views/Shared/EditorTemplates/{0}.cshtml" and/or "~/Views/Shared/EditorTemplates/{0}.ascx".
If you're using Razor you can create your own view engine that looks like this:
public class MyRazorViewEngine : RazorViewEngine { public MyRazorViewEngine() { PartialViewLocationFormats = PartialViewLocationFormats.Union(new[] { "~/Views/Shared/EditorTemplates/{0}.cshtml", }).ToArray(); } }
Register the view engine on application start in Global.asax.cs:
protected void Application_Start() { ViewEngines.Engines.Insert(0, new MyRazorViewEngine()); }
Thanks Mattias, but will this actually override the view being used by XForms? Isn't there more to it than you describe?
I don't know what EPiServer version you're on but on 7.19 it's all it takes. I'm doing it myself in a project of ours.
I think (but haven't tested) you can use "local" editor templates without custom view engine. Local editor template should be with higher priority over editor templates coming from Cms .zip file.
Well I've tried both methods suggested by Valdis and Mattias and my custom view is not being picked up.
I have added a view in the project, path ~/Views/Shared/EditorTemplates/InputFragment.cshtml, and this is not picked up so I added the custom view engine as suggested by Mattias and registered this in Application_Start event and it's still not being picked up.
Is there anything obvious that I've missed? The original file is .ascx and I have added .cshtml, do I need to do anything extra for this?
Thanks,
Mark
Hmm, strange. I have this working in a project running EPiServer 7.19.2. What version are you on? And are you using Razor and MVC in your project?
This is what my view engine PartialViewLocationFormats look like:
PartialViewLocationFormats = new[] { "~/Views/Shared/Blocks/{0}.cshtml", "~/Views/Shared/{0}.cshtml", "~/Views/Shared/PagePartials/{0}.cshtml", "~/Views/Shared/EditorTemplates/{0}.cshtml", "~/Views/{1}/{0}.cshtml" };
I just noticed I had to touch web.config or recompile for changes in InputFragment.cshtml to be registered.
Hi Mattias,
I now have the following based on your snippet:
public class MyIntranetRazorViewEngine : RazorViewEngine
{
public MyIntranetRazorViewEngine()
{
PartialViewLocationFormats = new[]
{
"~/Views/Shared/EditorTemplates/{0}.cshtml"
};
}
}
This class is in a folder called Business which is in the root of the project (does this need to be somewhere else?).
I have performed IIS reset and rebuilt the project several times and the custom view is still not being picked up.
Any other suggestions?
Thanks,
Mark
I was wrong about "no need to have a custom view engine". I thought EPiServer was using EditorFor, instead of manual partial view find for the fragment.
Can you add following code in your view and paste what's result of variable "partialView":
@{ var viewEngineWrapper = ServiceLocator.Current.GetInstance<CachingViewEnginesWrapper>(); ViewEngineResult partialView = viewEngineWrapper.FindPartialView(ViewContext, "SubmitFragment"); }
Also you may want to check out ViewEnginesCollection, to make sure that your view is registered correctly. Can you dump content of:
System.Web.Mvc.ViewEngines.Engines
Just to be sure, you have added a regular textbox to the XForm and still, the custom InputFragment.cshtml is not loaded? For other types of form elements you need to add custom fragments for them as well.
When I tested this I added this markup in InputFragment.cshtml:
@model EPiServer.XForms.Parsing.InputFragment <label title="@Model.Title" for="@Model.Reference"> @Html.DisplayFor(m => m.Label) </label> @Html.TextBox(Model.Reference, Server.HtmlDecode(Model.Value) ?? string.Empty, new { size = Model.Size, @class = Model.Class }) @Html.ValidationMessage(Model.ValidationReference)
Everything was loaded as expected, however when I made changes to the markup I had to touch web.config or rebuild.
As a next step I would do as Valdis says, but replace SubmitFragment with InputFragment. ;)
You can put this code in any of your page views to see the results.
Hi Mattias and Valdis,
I've found out the problem and got it working. I noticed that the application start event in Global.asax wasn't firing which meant that the custom view engine was not being inserted. I traced this to the namespace in the markup not matching the namespace in the codebehind file, now these match the view engine is being inserted and the correct view is being used.
Thank you both ever so much for your help with this,
Mark
Hi
Mark A,
Advise me please which response you will like me to mark as answer :)
Mattias and Valdis,
Thanks a lot
Regards
/K
Hi K,
I followed the advice of Mattias from his post of June 17 2015, 15:19 so this was the answer, although Valdis provided some good pointers as well especially from his post of June 25 2015, 7:01
Mark
However, 8.x they changed from Randon to Guid.New().
Also, I would recommend to insert ViewEngine from initializable module, as Global.asax may be actually optional to have in the site at all.
I agree about the initializable module recommendation. My bad for choosing the easiest road. :)
Hi,
CMS version: 7.19.1
We are having an issue in our QA enviornment where XForm is generating following HTML. (Works fine in Dev)
...
Title
.....
....
HTML is
@using (Html.BeginXForm(Model.Block.Form, new { Action = Model.Block.ActionUrl.ToString() }))
{
Html.RenderXForm(Model.Block.Form);
}
I am bit stuck, Where and what I need to investigate on QA enviornments?
Regards
Khurram