Другой вариант (и мой личный pereference) было бы просто поставить System.Web.Script.Serialization.ScriptIgnoreAttribute
на членов класса модели, которые вы не хотите сериализовать (или создать неявно складного класс DTO сделать то же самое) ,
Ex:
using System.Web.Script.Serialization;
public class User
{
[ScriptIgnore]
public int ID { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}
Таким образом, вам не нужно определить специальный интерфейс, вы можете поместить это право метаданных в вашей модели.
Update: Видимо, это не вариант, потому что класс является производным классом и его членов из (неизменяемо) базового класса, которые должны быть скрыты.
Это является можно динамически генерировать класс, как вы хотите, либо с помощью Emit
или динамический прокси-библиотеку, как замок, но это будет очень громоздким.Если вы можете, я очень рекомендую использовать простой прокси-класс, вместо этого:
public class UserResult
{
public UserResult(User user)
{
Username = user.Username;
Password = user.Password;
}
public string Username { get; set; }
public string Password { get; set; }
}
Или, если вы действительно не можете иметь дело с поддержанием этого, вы можете создать «общий» прокси: cоздателем экземпляров
static class ProxyInstantiator
{
public static TProxy CreateProxy<TProxy>(object source)
where TProxy : new()
{
TProxy proxy = new TProxy();
CopyProperties(source, proxy);
return proxy;
}
protected static void CopyProperties(object source, object dest)
{
if (dest == null)
{
throw new ArgumentNullException("dest");
}
if (source == null)
{
return;
}
Type sourceType = source.GetType();
PropertyInfo[] sourceProperties =
sourceType.GetProperties(BindingFlags.Instance | BindingFlags.Public);
Type destType = dest.GetType();
PropertyInfo[] destProperties =
destType.GetProperties(BindingFlags.Instance | BindingFlags.Public);
var propsToCopy =
from sp in sourceProperties
join dp in destProperties on sp.Name equals dp.Name
select new { SourceProperty = sp, DestProperty = dp };
foreach (var p in propsToCopy)
{
object sourceValue = p.SourceProperty.GetValue(o, null);
p.DestProperty.SetValue(dest, sourceValue, null);
}
}
}
Тогда вы можете написать простой прокси класс (не интерфейс):
public class UserResult
{
public string Username { get; set; }
public string Password { get; set; }
}
и вызвать его в методе контроллера, как это:
User someUser = GetSomeUser();
UserResult result = ProxyInstantiator.CreateProxy<UserResult>(someUser);
Слово предостережения об этом:
Это делает не принимать во внимание индексируется свойств и потерпит неудачу, если есть какие-либо из них. Он не учитывает «глубокое копирование» - если ваш исходный класс содержит ссылочные типы, он будет копировать только ссылки - возможно, это то, что вы хотите, может быть, это не так.
Лично я бы взял прежний подход и просто создал отдельные прокси-классы без общего прокси-сервера, потому что, если я ошибаюсь, я бы предпочел ошибку времени компиляции над ошибкой во время выполнения. Но вы спросили, так что вы идете!
Что вы хотите сказать? – jason
Я отредактировал мой вопрос! Простите. –
См. Http://stackoverflow.com/questions/1302946/asp-net-mvc-controlling-serialization-with-jsonresult – Jacob