Passing model via dynamic form parameter in . NET MVC

Asked

Viewed 263 times

4

I created this function to generate a handle (or slug, how to prefer) for the model users, the problem is that I would like to make it more "modular", so that I can easily implement in any other model that is also necessary to generate a Handle.

The model, which is a partial.

public partial class users
{
    ...

    public void Handle()
    {
        ...
    }
}

The function:

public void Handle()
{
    int length;
    string handle;
    List<int> list = new List<int>();

    handle = Slugify.Make(this.first_name + " " + this.last_name);
    length = (handle + "-").Length;

    this.handle = handle;

    using (Entities db = new Entities())
    {
        List<string> handles = db.users.Where(p => p.handle.Contains(handle) || p.handle.StartsWith(handle + "-"))
            .Select(p => p.handle)
            .ToList();

        if (handles.Count == 0 || handles.Contains(handle) == false)
        {
            this.handle = handle;
            return;
        }

        if (handles.Contains(handle) && handles.Count == 1)
        {
            this.handle = handle + "-" + 1;
            return;
        }

        foreach (string index in handles)
        {
            if ((index + "-").Length > length)
                list.Add(int.Parse(index.Remove(0, length)));
        }

        list.Sort();

        int suffix = list.Last();
        this.handle = handle + "-" + (suffix + 1);
    }
}

So I created a separate class that at first would receive as a parameter the model and then do basically what function Handle() does, but in a "modular" way, for example:

Passing as parameter:

users user = new users
{
    first_name = first_name,
    last_name = last_name,
    email = email,
    password = BCryptHelper.HashPassword(password, BCryptHelper.GenerateSalt(6))
    handle = Handle.Make(db.users, first_name + " " + last_name)
};

The function:

public class Handle
{
    public string Make(Type model, string handle)
    {
        db.Set<model>.Where(...) ...

        return handle;
    }
}

But I can not in any way pass as parameter the model db.users without specifically determining the type of model is users.

I’ve tried to public string Make(DbSet<dynamic> model... but also did not give...

1 answer

4


You can. Use generic:

public class Handle
{
    public string Make<T>(T model, string handle)
        where T: class
    {
        db.Set<T>.Where(...) ...

        return handle;
    }
}

EDIT

To parameterize the Where, according to your comments, you need to define an interface for T:

public interface IHandle
{
    public string handle { get; set; }
}

So you can use the Where:

public class Handle
{
    public string Make<T>(T model, string handle)
        where T: class, IHandle
    {
        db.Set<T>().Where(p => p.handle.Contains(handle) || p.handle.StartsWith(handle + "-"))

        return handle;
    }
}

EDIT 2

The way of calling the method is thus:

Handle.Make(user, "Rafael Alexandre");

I believe that db is accessible within the method. If it is not, it must be so:

    public string Make<T>(DbContext db, T model, string handle)
        where T: class, IHandle
    {
        db.Set<T>().Where(p => p.handle.Contains(handle) || p.handle.StartsWith(handle + "-"))

        return handle;
    }

There you call it:

Handle.Make(db, user, "Rafael Alexandre");
  • It worked partially, the problem is that the Handle parameter is not recognized in this Where: db.Set<T>().Where(p => p.handle.Contains(handle) || p.handle.StartsWith(handle + "-")).

  • 'T' does not contain a definition for handle

  • Ah, good. It means you have to set an interface to work. I will edit the answer.

  • It hasn’t worked yet. When I try to pass as parameter the Handle.Make(db.users, "Rafael Alexandre") the return is The type System.Data.Entity.DbSet<Models.users> cannot by as type parameter 'T' in generic type or method 'Handle.Make<T>(T, string).

  • 1

    No, young man. You don’t pass the whole context. It goes like this: Handle.Make(user, "Rafael Alexandre"), where user would be the user. I’ll edit the answer one more time because I don’t think it’s clear yet.

  • And if I want to access it (http://i.imgur.com/oP26o50.jpg) in any way that works, is it possible? ;users user = new users { handle = first_name + " " + last_name }

  • It is possible this way. Try to implement. If there is a problem, ask one more question.

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.