asp.net MVC example Project "Suteki.shop" Analysis of Modelbinder

Source: Internet
Author: User
Tags http request httpcontext

In Suteki.shop, the author constructs a modelbinder base class "DataBinder", which itself inherits from the Imodelbinder interface and derives other subclass classes such as Productbinder, and so on, with this class. It can be said that, in addition to the very few places, DataBinder was used to suteki.shop most of the modelbinder bound scenes.

First look at its class diagram structure:

As a base class, DataBinder (the lower left of the figure) implements converting the HTTP request data into the corresponding type in the model. The core approach is Bindmodel, and here's how to explain:

public virtual object BindModel(ControllerContext controllerContext,  ModelBindingContext bindingContext)
{
object entity;

if (declaringAttribute == null || declaringAttribute.Fetch)
{
entity =  FetchEntity(bindingContext, controllerContext);
}
else
{
entity =  Activator.CreateInstance(bindingContext.ModelType);
}

try
{
validatingBinder.UpdateFrom(entity,  controllerContext.HttpContext.Request.Form, bindingContext.ModelState,  bindingContext.ModelName);
}
catch(ValidationException ex)
{
//Ignore validation exceptions - they are stored in ModelState.
//The  controller can access the errors by inspecting the ModelState dictionary.
}

return entity;
}

The first thing to explain is declaringattribute, a variable that is actually a Databindattribute type instance, and its role is to determine whether the currently requested data is used to create new model information or to acquire and bind existing data records. The actual initialization of the instance is given to the Accept method (note that the declaration of the Accept method is defined in the Iacceptsattribute interface):

public void Accept(Attribute attribute)
{
declaringAttribute =  (DataBindAttribute) attribute;
}

The call to the method is placed in the Bindusingattribute Getbinder () method, so here's a look at the specific implementation of Bindusingattribute:

public class BindUsingAttribute : CustomModelBinderAttribute
{
private readonly Type binderType;

public BindUsingAttribute(Type  binderType)
{
if(!typeof(IModelBinder).IsAssignableFrom(binderType))
{
throw new InvalidOperationException("Type '{0}' does not implement  IModelBinder.".With(binderType.Name));
}

this.binderType =  binderType;
}

public override IModelBinder GetBinder()
{
var  binder = (IModelBinder) ServiceLocator.Current.GetInstance(binderType);

if (binder is IAcceptsAttribute)
{
((IAcceptsAttribute)binder).Accept(this);
}

return binder;
}
}

This property class is used for modelbinder binding in action, and its class constructor is initialized with a type parameter and used in the Getbinder () method Servicelocator to perform the final Modelbinder instantiation, note that in this method there is a logical judgment of the current binder (Iacceptsattribute), and to distinguish whether the modelbinder of the current action binding implements the Iacceptsattribute interface. If not implemented or Declaringattribute.fetch is true, the Fetchentity () method is invoked in the previous DataBinder class method "Bindmodel". Fetchentity retrieves the data from the primary key (PrimaryKey) in the submitted data and returns the object instance with the following code:

private object FetchEntity(ModelBindingContext bindingContext,  ControllerContext controllerContext)
{
object entity;
var primaryKey =  bindingContext.ModelType.GetPrimaryKey();//从Shop.dbml中查找相应的主键信息
string  name = bindingContext.ModelName + "." + primaryKey.Name;//拼接出要获取的主 键名称

string rawKeyValue = controllerContext.HttpContext.Request.Form [name];

if (string.IsNullOrEmpty(rawKeyValue))
{
throw new  InvalidOperationException("Could not find a value named '{0} '".With(name));
}

int key = Convert.ToInt32(rawKeyValue);
var repository = resolver.GetRepository(bindingContext.ModelType);
entity =  repository.GetById(key);
return entity;
}

Notice the two lines in the above code:

var repository = resolver.GetRepository(bindingContext.ModelType);
entity = repository.GetById(key);

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.