0

I need to get urls with string name and able to edit/update it.

public class Person
{
    public int Id {get; set;}
    public string Name { get; set; }
    public string LastName { get; set; }
    public string City { get; set; }
}

Controller

  public ActionResult Edit(int id)
    {
        var person = _personService.Find(id);
        PersonViewModel model = Mapper.Map<Person, PersonViewModel>(person);
        return PartialView("_Edit", model);
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit(PersonViewModel model)
    {
        if (ModelState.IsValid)
        {
            var person = _personService.Find(model.Id);

            person.Id = model.Id;
            person.Name = model.Name;
            person.LastName = model.LastName;
            person.City = model.City;

            _personService.Update(person);
            _uow.SaveChanges();
            return RedirectToAction("Index");
        }

        return PartialView("_Edit", model);
    }

View

    <div id="myModal" class="modal fade in">
        <div class="modal-dialog">
        <div class="modal-content">
            <div id="myModalContent"></div>
        </div>
    </div>
</div>
<div class="pull-right">@Html.ActionLink(" ", "Add", "Person", null, new { data_modal = "", id = "btnCreate", @class = "btn btn-md glyphicon glyphicon-plus" })</div>


@foreach(var person in Model)
{

    <p>@person.Name</p>
    <p>@person.LastName</p>
    <p>@person.City</p>
    @Html.ActionLink(" ", "Edit", "Person", new { id = person.Id}, new { data_modal = "", @class = "btn btn-danger btn-sm glyphicon glyphicon-edit" })

}

When I use like this there is no problem. And url is localhost/Person/Edit/1.

I want to get url like localhost/Person/Edit/John. And for details view the url must be localhost/Person/John instead of Person/Deatils/John.

In domain model I remove Id column then make the Name column primary [Key]. Using FindByName(name) in my repository, Edit(string name) in action and context.MapRoute( "Person", "Person/{action}/{name}", new { controller = "Person", action = "Index"} ); in route config I can achive this. But I can not edit Name column because it is primary key. I need name editable. So can i use the Id column as key so i can edit/update the name with no problem like in my first case but using urls like Edit/John with no id in it?

ArmanKond
  • 11
  • 1
  • 6

1 Answers1

0

You will need some form of unique value in the URL. Imagine if you have more than one john?

If you don't mind having a URL like /Person/Edit/1/John

Then, for your given scenario (untested)..

public class Person
{
    [Key]
    public int Id {get; set;}
    public string Name { get; set; }
    public string LastName { get; set; }
    public string City { get; set; }
}

Add a route:

context.MapRoute( "Person", "Person/{action}/{id}/{name}", new { controller = "Person", action = "Index", id = UrlParameter.Optional, name = UrlParameter.Optional} ); 

Action:

public ActionResult Edit(int id, string name)
{
    var person = _personService.Find(id);

    // Optional, but you may want to ensure the Url is correct. of if name is
   // missing add it.
    if(string.IsNullOrEmpty(name) || (person.Name.ToUrlFriendly() != name.ToUrlFriendly()))
    {
        return RedirectToRoute(..... new {id = person.Id, name = person.Name.ToUrlFirendly() });
    }

    PersonViewModel model = Mapper.Map<Person, PersonViewModel>(person);
    return PartialView("_Edit", model);
}

Note the ToUrlFriendly() this is to ensure the URL is a valid one, and will generate urls-like-this-one and remove invalid chars. See here for more details and implementation.

https://stackoverflow.com/a/25486/387809

Community
  • 1
  • 1
SimonGates
  • 5,961
  • 4
  • 40
  • 52
  • Thanks. Using name as slug I can make it work with ids. But I dont want to show ids anywhere. I can create, delete/john and I can show details like localhost/Person/John. But I cannot update it. I can update lastname and city but not name(imagine when creating John you mistype and saved Jonh and you want to correct it). – ArmanKond Mar 05 '15 at 15:05
  • I have also a class working ToFriendly. I have another problem with this. In another case I can use title column as Key. When I enter a title "this title" it becomes "this-title". I am checking title when I create new one so if I write again "this title" I can show to user a message "Title you entered is already in use". But if i enter "this title " (notice the whitespace at the end), then ToFriendly makes it "this-title" again but instead of showing friendly error message it shows yellow page with PK_ForignKEY conflict. This is another issue maybe, I can try to validate on seofriendly name. – ArmanKond Mar 05 '15 at 15:05
  • But my main problem is I cannot update Person/Edit/John when i use name column as Key. So there is no way to do this without ids? I can also try first delete and then recreate on edit action but then it can be a problem if I have relational tables? – ArmanKond Mar 05 '15 at 15:06