I have a strange problem where I have an Edit view that renders disabled textbox for slug, so user can see the slug of the content he is editing but cannot change it. The slug can only be changed on the Create view where the textbox is enabled. In Edit view only Title can be changed.
In edit view the Slug textbox gets populated from the ViewModel passed in and this works.
However, when posting back the changes, the slug does not get posted in the Edit view for one content type (which is, I believe, the correct behaviour) and as such Model.IsValid (because I have the Required attribute attached to Slug property) fails. This is, as said, most likely the correct behaviour.
The thing is in the Edit view for another type of content the disabled textbox's content gets posted and the posted View Model is valid and I can even see the value for the Slug unchanged.
I could post code but those are quite huge views, however the relevant section of code which renders the Title and Slug textboxes is the same for both Create/Edit view and across the two content types and it is this:
<div class="editor-label">
<%= Html.LabelFor(model => model.Title, Resources.Localize.Section_Title)%>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(model => model.Title) %>
<%= Html.ValidationMessageFor(model => model.Title) %>
</div>
<div class="editor-label">
<%= Html.LabelFor(model => model.Slug, Resources.Localize.Section_Slug)%>
</div>
<div class="editor-field">
<% if (string.IsNullOrWhiteSpace(Model.Slug))
{ %>
<%= Html.TextBoxFor(model => model.Slug)%>
<% }
else
{ %>
<%= Html.TextBoxFor(model => model.Slug, new { disabled = true })%>
<% } %>
<%= Html.ValidationMessageFor(model => model.Slug) %>
</div>
I am using one partial view for both Create and Edit, that's why there's that if...else... statement because we only disable the Slug textbox when editing.
Hopefully someone has a clue about this because I just can't figure it out.
UPDATE:
The wierdest thing. These lines
<form id="Page-CreateEditForm" action="<%=Url.Action(Url.RequestContext.RouteData.GetRequiredString("action"), Url.RequestContext.RouteData.GetRequiredString("controller")) %>" enctype="multipart/form-data" method="post">
<form id="Section-CreateEditForm" action="<%=Url.Action(Url.RequestContext.RouteData.GetRequiredString("action"), Url.RequestContext.RouteData.GetRequiredString("controller")) %>" enctype="multipart/form-data" method="post">
in my Views (the same in both) generate these:
Form start tag when editing page "Test page". Slug: test-page. Notice the slug in the action!
<form id="Page-CreateEditForm" action="/Page/Edit/test-page" enctype="multipart/form-data" method="post">
Form start tag when editing section "Test section". Slug: test-section. Notice how the slug is missing after Edit.
<form id="Section-CreateEditForm" action="/Section/Edit" enctype="multipart/form-data" method="post">
Now the question becomes why would the same form tag definition result in two different actions at runtime?
FOLLOW UP:
Of course, after quick thought this must stem from the routes definitions in global.asax.cs, so let's check it out there. This is what we find:
routes.MapRoute(Localize.Routes_PagesEdit, RouteType.Admin, "Page/Edit/{slug}",
new {controller = "Page", action = "Edit", slug = ""}, null);
routes.MapRoute(
Localize.Routes_SectionsEdit,
RouteType.Regular,
"Section/Edit",
new {controller = "Section", action = "Edit"}, null
);
See how the Section Edit route is missing {slug} parameter. I believe I'm getting close to the solution.