I hope someone can come up with something better, but this is at least something.
In the main (non-partial) view I have a section at the top that defines the ids and names I need to use in multiple places in C#, HTML and JavaScript:
@{
const string PersonListId = "PersonList";
const string PersonDetailsId = "PersonDetails";
const string CurrentPersonIdName = "CurrentPersonId";
}
At the bottom, I have a script section that assigns the strings to suitable namespace container objects:
<script type="text/javascript">
MyNamespace = {};
MyNamespace.Ids = {};
MyNamespace.Names = {};
MyNamespace.Ids.PersonList = '@Html.Raw(PersonListId)';
MyNamespace.Ids.PersonDetails = '@Html.Raw(PersonDetailsId)';
MyNamespace.Names.CurrentPersonId = '@Html.Raw(CurrentPersonIdName)';
</script>
In each partial view that introduces additional items that I need to reference by id or name, I add similar code to extend MyNamespace.Ids
and MyNamespace.Names
with the required strings.
Now I can use the C# string constants in Razor view code to generate markup with the right ids and names and I can write regular static JavaScript files that reference MyNamespace.Ids
and MyNamespace.Names
to find the right ids and names, e.g. in jQuery selectors.
I also added similar stuff for action URLs that my Ajax calls use, and put them in MyNamespace.Urls
:
MyNamespace.Urls.GetPerson = '@Html.Raw(Url.Action("GetPerson"))';
It's not ideal but it's straightforward and solves the most pressing issue of magic strings scattered all over the place. It will not detect errors at compile time, but renaming items will require a single string to be renamed at a single place, and if I rename or misspell MyNamespace.Ids.Something
it will at least generate a runtime JavaScript error that can be seen in a JS console or similar.