Search code examples
asp.net-mvcroutesasp.net-mvc-5

MVC 5 Routes - Using URL string einstead GUID


I'm using Custom URL strng for friendly URL SEO. Here is my model:

[Table("UserProfiles")]
public class UserProfile
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }
    public virtual ApplicationUser User { get; set; }
    public string UserId { get; set; }
    public DateTime CreatedAt { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public string UrlSeo { get; set; }
}

So I need to do next things: Using default routing like this https://localhost/UserProfiles/Details/Guid_Here. This working fine by default. Next I want to display user url like this: https://localhost/User_url_Seo_Here And one more thing: https://localhost/UserProfiles/User_url_here So then I'm Changing routes one of my models not working and giving me 400 bad request Here is my controller example:

// GET: UserProfiles/Details/5
public async Task<ActionResult> Details(Guid? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    UserProfile userProfile = await db.UserProfiles.FindAsync(id);
    if (userProfile == null)
    {
        return HttpNotFound();
    }
    return View(userProfile);
}

No my routes: If I'm Using routes like this:

 routes.MapRoute(
    name: "DetailUserProfile",
    url: "UserProfiles/{id}",
    defaults: new
    {
        controller = "UserProfiles",
        action = "Details",
        ident = UrlParameter.Optional
    }
);

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

It removes action name on details but CRUD not working. If I use controller like this:

// GET: UserProfiles/View/5
public async Task<ActionResult> ViewProfile(string urlseo)
{
    if (urlseo == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    UserProfile userProfile = await db.UserProfiles.FirstOrDefaultAsync(x => x.UrlSeo == urlseo);
    if (userProfile == null)
    {
        return HttpNotFound();
    }
    return View(userProfile);
}

And route like this:

routes.MapRoute(
   name: "ViewUserProfile5",
   url: "UserProfiles/{action}/{urlseo}",
   defaults: new
   {
       controller = "UserProfiles",
       action = "ViewProfile",
       urlseo = UrlParameter.Optional
   }
);

I'm recive HTTP Error 400.0 - Bad Request But if I'm changing var = UrlParameter.Optional it works fine, not so fine but controller with custom url working but CRUD operation stopped work.


Solution

  • I'm not writing on C# anymore but faced one mistake in my old code and know solution: 5 Years after but: Problem is that I'm waiting for GUID as id but passing string, inspiration came from node.js, python flask and java spring boot. So if I turn to this:

    / GET: UserProfiles/Details/5
    public async Task<ActionResult> Details(String? id)
    {
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    UserProfile userProfile = await db.UserProfiles.FindAsync(id);
    if (userProfile == null)
    {
        return HttpNotFound();
    }
    return View(userProfile);
    }
    

    It will work, thanks for comments but no one noticed this thing.